Open individual database connections where we need them. Do not use global pointers anywhere. This may mean we have more than one connection open at the sae time. SQLite3 will take care of thread-safety.

Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
DL6ER 2021-03-20 20:15:44 +00:00
parent 7b8bc6d0dd
commit 0795cf6209
No known key found for this signature in database
GPG Key ID: 00135ACBD90B28DD
21 changed files with 624 additions and 656 deletions

1
.gitignore vendored
View File

@ -21,3 +21,4 @@ version*
# MAC->Vendor database files
tools/manuf.data
tools/macvendor.db
node_modules

View File

@ -1228,9 +1228,10 @@ void getDBstats(const int *sock)
format_memory_size(prefix, filesize, &formated);
if(istelnet[*sock])
ssend(*sock,"queries in database: %i\ndatabase filesize: %.2f %sB\nSQLite version: %s\n", get_number_of_queries_in_DB(), formated, prefix, get_sqlite3_version());
ssend(*sock, "queries in database: %i\ndatabase filesize: %.2f %sB\nSQLite version: %s\n",
get_number_of_queries_in_DB(NULL), formated, prefix, get_sqlite3_version());
else {
pack_int32(*sock, get_number_of_queries_in_DB());
pack_int32(*sock, get_number_of_queries_in_DB(NULL));
pack_int64(*sock, filesize);
if(!pack_str32(*sock, (char *) get_sqlite3_version()))

View File

@ -166,12 +166,6 @@ void process_request(const char *client_message, int *sock)
read_regex_from_database();
unlock_shm();
}
else if(command(client_message, ">update-mac-vendor"))
{
processed = true;
logg("Received API request to update vendors in network table");
updateMACVendorRecords();
}
else if(command(client_message, ">delete-lease"))
{
processed = true;

View File

@ -203,9 +203,8 @@ void cleanup(const int ret)
}
logg("All threads joined");
// Close database connections
// Close database connection
gravityDB_close();
dbclose();
// Close sockets and delete Unix socket file handle
close_telnet_socket();

View File

@ -20,18 +20,18 @@
// getAliasclientIDfromIP()
#include "network-table.h"
bool create_aliasclients_table(void)
bool create_aliasclients_table(sqlite3 *db)
{
// Create aliasclient table in the database
SQL_bool("CREATE TABLE aliasclient (id INTEGER PRIMARY KEY NOT NULL, " \
"name TEXT NOT NULL, " \
"comment TEXT);");
SQL_bool(db, "CREATE TABLE aliasclient (id INTEGER PRIMARY KEY NOT NULL, " \
"name TEXT NOT NULL, " \
"comment TEXT);");
// Add aliasclient_id to network table
SQL_bool("ALTER TABLE network ADD COLUMN aliasclient_id INTEGER;");
SQL_bool(db, "ALTER TABLE network ADD COLUMN aliasclient_id INTEGER;");
// Update database version to 9
if(!db_set_FTL_property(DB_VERSION, 9))
if(!db_set_FTL_property(db, DB_VERSION, 9))
{
logg("create_aliasclients_table(): Failed to update database version!");
return false;
@ -93,12 +93,12 @@ static void recompute_aliasclient(const int aliasclientID)
}
// Store hostname of device identified by dbID
bool import_aliasclients(void)
bool import_aliasclients(sqlite3 *db)
{
sqlite3_stmt *stmt = NULL;
const char querystr[] = "SELECT id,name FROM aliasclient";
int rc = sqlite3_prepare_v2(FTL_db, querystr, -1, &stmt, NULL);
int rc = sqlite3_prepare_v2(db, querystr, -1, &stmt, NULL);
if(rc != SQLITE_OK)
{
logg("import_aliasclients() - SQL error prepare: %s", sqlite3_errstr(rc));
@ -166,7 +166,7 @@ bool import_aliasclients(void)
return true;
}
static int get_aliasclient_ID(const clientsData *client)
static int get_aliasclient_ID(sqlite3 *db, const clientsData *client)
{
// Skip alias-clients themselves
if(client->flags.aliasclient)
@ -180,7 +180,7 @@ static int get_aliasclient_ID(const clientsData *client)
}
// Get aliasclient ID from database (DB index)
const int aliasclient_DBid = getAliasclientIDfromIP(clientIP);
const int aliasclient_DBid = getAliasclientIDfromIP(db, clientIP);
// Compare DB index for all alias-clients stored in FTL
int aliasclientID = 0;
@ -217,14 +217,31 @@ static int get_aliasclient_ID(const clientsData *client)
return -1;
}
void reset_aliasclient(clientsData *client)
void reset_aliasclient(sqlite3 *db, clientsData *client)
{
// Open pihole-FTL.db database file if needed
bool db_opened = false;
if(db == NULL)
{
if((db = dbopen(false)) == NULL)
{
logg("reimport_aliasclients() - Failed to open DB");
return;
}
// Successful
db_opened = true;
}
// Skip alias-clients themselves
if(client->flags.aliasclient)
return;
// Find corresponding alias-client (if any)
client->aliasclient_id = get_aliasclient_ID(client);
client->aliasclient_id = get_aliasclient_ID(db, client);
if(db_opened)
dbclose(&db);
// Skip if there is no responsible alias-client
if(client->aliasclient_id == -1)
@ -273,15 +290,22 @@ int *get_aliasclient_list(const int aliasclientID)
// Reimport alias-clients from database
// Note that this will always only change or add new clients. Alias-clients are
// removed by nulling them before importing new clients
void reimport_aliasclients(void)
void reimport_aliasclients(sqlite3 *db)
{
// Open pihole-FTL.db database file if needed
const bool db_already_open = FTL_DB_avail();
if(!db_already_open && !dbopen())
bool db_opened = false;
if(db == NULL)
{
logg("reimport_aliasclients() - Failed to open DB");
return;
if((db = dbopen(false)) == NULL)
{
logg("reimport_aliasclients() - Failed to open DB");
return;
}
// Successful
db_opened = true;
}
// Loop over all existing alias-clients and set their counters to zero
for(int clientID = 0; clientID < counters->clients; clientID++)
{
@ -298,10 +322,7 @@ void reimport_aliasclients(void)
}
// Import aliasclients from database table
import_aliasclients();
if(!db_already_open)
dbclose();
import_aliasclients(db);
// Recompute all alias-clients
for(int clientID = 0; clientID < counters->clients; clientID++)
@ -312,6 +333,10 @@ void reimport_aliasclients(void)
if(client == NULL || client->flags.aliasclient)
continue;
reset_aliasclient(client);
reset_aliasclient(db, client);
}
// Close the database if we opened it here
if(db_opened)
dbclose(&db);
}

View File

@ -13,12 +13,12 @@
// type clientsData
#include "../datastructure.h"
void reset_aliasclient(clientsData *client);
bool create_aliasclients_table(void);
bool import_aliasclients(void);
void reimport_aliasclients(void);
bool create_aliasclients_table(sqlite3 *db);
bool import_aliasclients(sqlite3 *db);
void reimport_aliasclients(sqlite3 *db);
int *get_aliasclient_list(const int aliasclientID);
void reset_aliasclient(sqlite3 *db, clientsData *client);
#endif //ALIASCLIENTS_TABLE_H

View File

@ -24,93 +24,57 @@
// import_aliasclients()
#include "aliasclients.h"
sqlite3 *FTL_db = NULL;
bool DBdeleteoldqueries = false;
long int lastdbindex = 0;
static bool db_avail = false;
static pthread_mutex_t dblock;
__attribute__ ((pure)) bool FTL_DB_avail(void)
void _dbclose(sqlite3 **db, const char *func, const int line, const char *file)
{
return db_avail;
}
void dbclose(void)
{
// Mark database as being closed
db_avail = false;
if(config.debug & DEBUG_LOCKS)
logg("Unlocking FTL database");
if(config.debug & DEBUG_DATABASE)
logg("Closing FTL database in %s() (%s:%i)", func, file, line);
// Only try to close an existing database connection
int rc = SQLITE_OK;
if( FTL_db != NULL )
if(db != NULL && *db != NULL)
{
if(config.debug & DEBUG_DATABASE)
logg("Closing FTL database");
if((rc = sqlite3_close(FTL_db)) != SQLITE_OK)
if((rc = sqlite3_close(*db)) != SQLITE_OK)
logg("Encountered error while trying to close database: %s", sqlite3_errstr(rc));
FTL_db = NULL;
*db = NULL;
}
else if(config.debug & DEBUG_LOCKS)
logg("Unlocking FTL database: already NULL");
// Unlock mutex on the database
pthread_mutex_unlock(&dblock);
if(config.debug & DEBUG_LOCKS)
logg("Unlocking FTL database: Success");
}
bool dbopen(void)
sqlite3* _dbopen(bool create, const char *func, const int line, const char *file)
{
// Skip subroutine altogether when database is already open
if(FTL_db != NULL && FTL_DB_avail())
{
if(config.debug & DEBUG_LOCKS)
logg("Not locking FTL database (already open)");
return true;
}
if(config.debug & DEBUG_LOCKS)
logg("Locking FTL database");
// Lock mutex on the database
pthread_mutex_lock(&dblock);
if(config.debug & DEBUG_LOCKS)
logg("Locking FTL database: Success");
// Try to open database
if(config.debug & DEBUG_DATABASE)
logg("Opening FTL database");
int rc = sqlite3_open_v2(FTLfiles.FTL_db, &FTL_db, SQLITE_OPEN_READWRITE, NULL);
logg("Opening FTL database in %s() (%s:%i)", func, file, line);
int flags = SQLITE_OPEN_READWRITE;
if(create)
flags |= SQLITE_OPEN_CREATE;
sqlite3 *db = NULL;
int rc = sqlite3_open_v2(FTLfiles.FTL_db, &db, flags, NULL);
if( rc != SQLITE_OK )
{
logg("Encountered error while trying to open database: %s", sqlite3_errstr(rc));
pthread_mutex_unlock(&dblock);
return false;
logg("Error while trying to open database: %s", sqlite3_errstr(rc));
return NULL;
}
// Explicitly set busy handler to value defined in FTL.h
rc = sqlite3_busy_timeout(FTL_db, DATABASE_BUSY_TIMEOUT);
rc = sqlite3_busy_timeout(db, DATABASE_BUSY_TIMEOUT);
if( rc != SQLITE_OK )
{
logg("Encountered error while trying to set busy timeout (%d ms) on database: %s",
logg("Error while trying to set busy timeout (%d ms) on database: %s",
DATABASE_BUSY_TIMEOUT, sqlite3_errstr(rc));
dbclose();
return false;
dbclose(&db);
return NULL;
}
db_avail = true;
return true;
return db;
}
int dbquery(const char *format, ...)
int dbquery(sqlite3* db, const char *format, ...)
{
va_list args;
va_start(args, format);
@ -125,7 +89,7 @@ int dbquery(const char *format, ...)
// Log generated SQL string when dbquery() is called
// although the database connection is not available
if(!FTL_DB_avail())
if(db == NULL)
{
logg("dbquery(\"%s\") called but database is not available!", query);
sqlite3_free(query);
@ -137,12 +101,12 @@ int dbquery(const char *format, ...)
logg("dbquery: \"%s\"", query);
}
int rc = sqlite3_exec(FTL_db, query, NULL, NULL, NULL);
int rc = sqlite3_exec(db, query, NULL, NULL, NULL);
if( rc != SQLITE_OK ){
logg("ERROR: SQL query \"%s\" failed: %s",
query, sqlite3_errstr(rc));
sqlite3_free(query);
dbclose();
dbclose(&db);
return rc;
}
@ -158,63 +122,51 @@ int dbquery(const char *format, ...)
return SQLITE_OK;
}
static bool create_counter_table(void)
static bool create_counter_table(sqlite3* db)
{
// Create FTL table in the database (holds properties like database version, etc.)
SQL_bool("CREATE TABLE counters ( id INTEGER PRIMARY KEY NOT NULL, value INTEGER NOT NULL );");
SQL_bool(db, "CREATE TABLE counters ( id INTEGER PRIMARY KEY NOT NULL, value INTEGER NOT NULL );");
// ID 0 = total queries
if(!db_set_counter(DB_TOTALQUERIES, 0))
return false;
db_set_counter(db, DB_TOTALQUERIES, 0);
// ID 1 = total blocked queries
if(!db_set_counter(DB_BLOCKEDQUERIES, 0))
return false;
db_set_counter(db, DB_BLOCKEDQUERIES, 0);
// Time stamp of creation of the counters database
if(!db_set_FTL_property(DB_FIRSTCOUNTERTIMESTAMP, time(NULL)))
return false;
db_set_counter(db, DB_FIRSTCOUNTERTIMESTAMP, (unsigned long)time(0));
// Update database version to 2
if(!db_set_FTL_property(DB_VERSION, 2))
return false;
db_set_FTL_property(db, DB_VERSION, 2);
return true;
}
static bool db_create(void)
{
int rc = sqlite3_open_v2(FTLfiles.FTL_db, &FTL_db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
if( rc != SQLITE_OK )
{
logg("Encountered error while trying to create database in rw-mode: %s", sqlite3_errstr(rc));
sqlite3 *db = dbopen(true);
if(db == NULL)
return false;
}
// Mark database as being available so dbquery() doesn't error out
db_avail = true;
// Create Queries table in the database
SQL_bool("CREATE TABLE queries ( id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp INTEGER NOT NULL, type INTEGER NOT NULL, status INTEGER NOT NULL, domain TEXT NOT NULL, client TEXT NOT NULL, forward TEXT );");
SQL_bool(db, "CREATE TABLE queries ( id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp INTEGER NOT NULL, type INTEGER NOT NULL, status INTEGER NOT NULL, domain TEXT NOT NULL, client TEXT NOT NULL, forward TEXT );");
// Add an index on the timestamps (not a unique index!)
SQL_bool("CREATE INDEX idx_queries_timestamps ON queries (timestamp);");
SQL_bool(db, "CREATE INDEX idx_queries_timestamps ON queries (timestamp);");
// Create FTL table in the database (holds properties like database version, etc.)
SQL_bool("CREATE TABLE ftl ( id INTEGER PRIMARY KEY NOT NULL, value BLOB NOT NULL );");
SQL_bool(db, "CREATE TABLE ftl ( id INTEGER PRIMARY KEY NOT NULL, value BLOB NOT NULL );");
// Set FTL_db version 1
if(dbquery("INSERT INTO ftl (ID,VALUE) VALUES(%i,1);", DB_VERSION) != SQLITE_OK)
if(!db_set_FTL_property(db, DB_VERSION, 1))
return false;
// Most recent timestamp initialized to 00:00 1 Jan 1970
if(dbquery("INSERT INTO ftl (ID,VALUE) VALUES(%i,0);", DB_LASTTIMESTAMP) != SQLITE_OK)
if(!db_set_FTL_property(db, DB_LASTTIMESTAMP, 0))
return false;
// Done initializing the database
// Close database handle, it will be reopened in db_init()
dbclose();
// Close database handle
dbclose(&db);
// Explicitly set permissions to 0644
// 644 = u+w u+r g+r o+r
@ -234,15 +186,6 @@ void SQLite3LogCallback(void *pArg, int iErrCode, const char *zMsg)
void db_init(void)
{
// Initialize database lock mutex
int rc;
if((rc = pthread_mutex_init(&dblock, NULL)) != 0)
{
logg("FATAL: FTL_db mutex init failed (%s, %i)\n", strerror(rc), rc);
// Return failure
exit(EXIT_FAILURE);
}
// Initialize SQLite3 logging callback
// This ensures SQLite3 errors and warnings are logged to pihole-FTL.log
// We use this to possibly catch even more errors in places we do not
@ -259,22 +202,19 @@ void db_init(void)
if (!db_create())
{
logg("Creation of database failed, database is not available");
pthread_mutex_unlock(&dblock);
return;
}
}
// Open database
dbopen();
db_avail = true;
sqlite3 *db = dbopen(false);
// Test FTL_db version and see if we need to upgrade the database file
int dbversion = db_get_FTL_property(DB_VERSION);
int dbversion = db_get_int(db, DB_VERSION);
if(dbversion < 1)
{
logg("Database not available, please ensure the database is unlocked when starting pihole-FTL !");
dbclose();
dbclose(&db);
return;
}
else
@ -288,14 +228,14 @@ void db_init(void)
{
// Update to version 2: Create counters table
logg("Updating long-term database to version 2");
if (!create_counter_table())
if (!create_counter_table(db))
{
logg("Counter table not initialized, database not available");
dbclose();
dbclose(&db);
return;
}
// Get updated version
dbversion = db_get_FTL_property(DB_VERSION);
dbversion = db_get_int(db, DB_VERSION);
}
// Update to version 3 if lower
@ -303,14 +243,14 @@ void db_init(void)
{
// Update to version 3: Create network table
logg("Updating long-term database to version 3");
if (!create_network_table())
if (!create_network_table(db))
{
logg("Network table not initialized, database not available");
dbclose();
dbclose(&db);
return;
}
// Get updated version
dbversion = db_get_FTL_property(DB_VERSION);
dbversion = db_get_int(db, DB_VERSION);
}
// Update to version 4 if lower
@ -318,14 +258,14 @@ void db_init(void)
{
// Update to version 4: Unify clients in network table
logg("Updating long-term database to version 4");
if(!unify_hwaddr())
if(!unify_hwaddr(db))
{
logg("Unable to unify clients in network table, database not available");
dbclose();
dbclose(&db);
return;
}
// Get updated version
dbversion = db_get_FTL_property(DB_VERSION);
dbversion = db_get_int(db, DB_VERSION);
}
// Update to version 5 if lower
@ -333,14 +273,14 @@ void db_init(void)
{
// Update to version 5: Create network-addresses table
logg("Updating long-term database to version 5");
if(!create_network_addresses_table())
if(!create_network_addresses_table(db))
{
logg("Network-addresses table not initialized, database not available");
dbclose();
dbclose(&db);
return;
}
// Get updated version
dbversion = db_get_FTL_property(DB_VERSION);
dbversion = db_get_int(db, DB_VERSION);
}
// Update to version 6 if lower
@ -348,14 +288,14 @@ void db_init(void)
{
// Update to version 6: Create message table
logg("Updating long-term database to version 6");
if(!create_message_table())
if(!create_message_table(db))
{
logg("Message table not initialized, database not available");
dbclose();
dbclose(&db);
return;
}
// Get updated version
dbversion = db_get_FTL_property(DB_VERSION);
dbversion = db_get_int(db, DB_VERSION);
}
// Update to version 7 if lower
@ -363,15 +303,15 @@ void db_init(void)
{
// Update to version 7: Create message table
logg("Updating long-term database to version 7");
if(dbquery("ALTER TABLE queries ADD COLUMN additional_info TEXT;") != SQLITE_OK ||
!db_set_FTL_property(DB_VERSION, 7))
if(dbquery(db, "ALTER TABLE queries ADD COLUMN additional_info TEXT;") != SQLITE_OK ||
!dbquery(db, "INSERT OR REPLACE INTO ftl (id, value) VALUES ( %u, %i );", DB_VERSION, 7) != SQLITE_OK)
{
logg("Column additional_info not initialized, database not available");
dbclose();
dbclose(&db);
return;
}
// Get updated version
dbversion = db_get_FTL_property(DB_VERSION);
dbversion = db_get_int(db, DB_VERSION);
}
// Update to version 8 if lower
@ -379,14 +319,14 @@ void db_init(void)
{
// Update to version 8: Add name field to network_addresses table
logg("Updating long-term database to version 8");
if(!create_network_addresses_with_names_table())
if(!create_network_addresses_with_names_table(db))
{
logg("Network addresses table not initialized, database not available");
dbclose();
dbclose(&db);
return;
}
// Get updated version
dbversion = db_get_FTL_property(DB_VERSION);
dbversion = db_get_int(db, DB_VERSION);
}
// Update to version 9 if lower
@ -394,21 +334,21 @@ void db_init(void)
{
// Update to version 9: Add aliasclients table
logg("Updating long-term database to version 9");
if(!create_aliasclients_table())
if(!create_aliasclients_table(db))
{
logg("Aliasclients table not initialized, database not available");
dbclose();
dbclose(&db);
return;
}
// Get updated version
dbversion = db_get_FTL_property(DB_VERSION);
dbversion = db_get_int(db, DB_VERSION);
}
import_aliasclients();
import_aliasclients(db);
// Close database to prevent having it opened all time
// We already closed the database when we returned earlier
dbclose();
dbclose(&db);
// Log if users asked us to not use the long-term database for queries
// We will still use it to store warnings in it
@ -422,100 +362,70 @@ void db_init(void)
logg("Database successfully initialized");
}
int db_get_FTL_property(const enum ftl_table_props ID)
int db_get_int(sqlite3* db, const enum ftl_table_props ID)
{
if(!FTL_DB_avail())
{
logg("db_get_FTL_property(%u) called but database is not available!", ID);
return DB_FAILED;
}
// Prepare SQL statement
char* querystr = NULL;
int ret = asprintf(&querystr, "SELECT VALUE FROM ftl WHERE id = %u;", ID);
if(querystr == NULL || ret < 0)
{
logg("Memory allocation failed in db_get_FTL_property with ID = %u (%i)", ID, ret);
logg("Memory allocation failed in db_get_int db, with ID = %u (%i)", ID, ret);
return DB_FAILED;
}
int value = db_query_int(querystr);
int value = db_query_int(db, querystr);
free(querystr);
return value;
}
bool db_set_FTL_property(const enum ftl_table_props ID, const int value)
bool db_set_FTL_property(sqlite3 *db, const enum ftl_table_props ID, const long value)
{
if(!FTL_DB_avail())
{
logg("db_set_FTL_property(%u, %i) called but database is not available!", ID, value);
return false;
}
return dbquery("INSERT OR REPLACE INTO ftl (id, value) VALUES ( %u, %i );", ID, value) == SQLITE_OK;
return dbquery(db, "INSERT OR REPLACE INTO ftl (id, value) VALUES ( %u, %ld );", ID, value) == SQLITE_OK;
}
bool db_set_counter(const enum counters_table_props ID, const int value)
bool db_set_counter(sqlite3 *db, const enum counters_table_props ID, const long value)
{
if(!FTL_DB_avail())
if(dbquery(db, "INSERT OR REPLACE INTO counters (id, value) VALUES ( %u, %ld );", ID, value) != SQLITE_OK)
{
logg("db_set_counter(%u, %i) called but database is not available!", ID, value);
return false;
}
if(dbquery("INSERT OR REPLACE INTO counters (id, value) VALUES ( %u, %i );", ID, value) != SQLITE_OK)
{
dbclose();
dbclose(&db);
return false;
}
return true;
}
bool db_update_counters(const int total, const int blocked)
bool db_update_counters(sqlite3 *db, const int total, const int blocked)
{
if(!FTL_DB_avail())
if(dbquery(db, "UPDATE counters SET value = value + %i WHERE id = %i;", total, DB_TOTALQUERIES) != SQLITE_OK)
{
logg("db_update_counters(%i, %i) called but database is not available!", total, blocked);
dbclose();
dbclose(&db);
return false;
}
if(dbquery("UPDATE counters SET value = value + %i WHERE id = %i;", total, DB_TOTALQUERIES) != SQLITE_OK)
if(dbquery(db, "UPDATE counters SET value = value + %i WHERE id = %i;", blocked, DB_BLOCKEDQUERIES) != SQLITE_OK)
{
dbclose();
return false;
}
if(dbquery("UPDATE counters SET value = value + %i WHERE id = %i;", blocked, DB_BLOCKEDQUERIES) != SQLITE_OK)
{
dbclose();
dbclose(&db);
return false;
}
return true;
}
int db_query_int(const char* querystr)
int db_query_int(sqlite3 *db, const char* querystr)
{
if(!FTL_DB_avail())
{
logg("db_query_int(\"%s\") called but database is not available!", querystr);
return DB_FAILED;
}
if(config.debug & DEBUG_DATABASE)
{
logg("dbquery: \"%s\"", querystr);
}
sqlite3_stmt* stmt;
int rc = sqlite3_prepare_v2(FTL_db, querystr, -1, &stmt, NULL);
int rc = sqlite3_prepare_v2(db, querystr, -1, &stmt, NULL);
if( rc != SQLITE_OK )
{
if( rc != SQLITE_BUSY )
logg("Encountered prepare error in db_query_int(\"%s\"): %s", querystr, sqlite3_errstr(rc));
return DB_FAILED;
}
@ -525,21 +435,15 @@ int db_query_int(const char* querystr)
if( rc == SQLITE_ROW )
{
result = sqlite3_column_int(stmt, 0);
if(config.debug & DEBUG_DATABASE)
{
logg(" ---> Result %i (int)", result);
}
}
else if( rc == SQLITE_DONE )
{
// No rows available
result = DB_NODATA;
if(config.debug & DEBUG_DATABASE)
{
logg(" ---> No data");
}
}
else
{
@ -551,14 +455,8 @@ int db_query_int(const char* querystr)
return result;
}
long int get_max_query_ID(void)
long int get_max_query_ID(sqlite3 *db)
{
if(!FTL_DB_avail())
{
logg("get_max_query_ID() called but database is not available!");
return DB_FAILED;
}
const char *sql = "SELECT MAX(ID) FROM queries";
if(config.debug & DEBUG_DATABASE)
{
@ -566,13 +464,13 @@ long int get_max_query_ID(void)
}
sqlite3_stmt* stmt = NULL;
int rc = sqlite3_prepare_v2(FTL_db, sql, -1, &stmt, NULL);
int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
if( rc != SQLITE_OK )
{
if( rc != SQLITE_BUSY )
{
logg("Encountered prepare error in get_max_query_ID(): %s", sqlite3_errstr(rc));
dbclose();
dbclose(&db);
}
// Return okay if the database is busy
@ -583,7 +481,7 @@ long int get_max_query_ID(void)
if( rc != SQLITE_ROW )
{
logg("Encountered step error in get_max_query_ID(): %s", sqlite3_errstr(rc));
dbclose();
dbclose(&db);
return DB_FAILED;
}
@ -596,17 +494,6 @@ long int get_max_query_ID(void)
return result;
}
// Returns ID of the most recent successful INSERT.
long get_lastID(void)
{
if(!FTL_DB_avail())
{
logg("get_lastID() called but database is not available!");
return DB_FAILED;
}
return sqlite3_last_insert_rowid(FTL_db);
}
// Return SQLite3 engine version string
const char *get_sqlite3_version(void)
{

View File

@ -26,31 +26,31 @@ enum counters_table_props {
} __attribute__ ((packed));
void db_init(void);
int db_get_FTL_property(const enum ftl_table_props ID);
bool db_set_FTL_property(const enum ftl_table_props ID, const int value);
int db_get_int(sqlite3* db, const enum ftl_table_props ID);
bool db_set_FTL_property(sqlite3 *db, const enum ftl_table_props ID, const long value);
bool db_set_counter(sqlite3 *db, const enum counters_table_props ID, const long value);
/// Execute a formatted SQL query and get the return code
int dbquery(const char *format, ...);
int dbquery(sqlite3* db, const char *format, ...) __attribute__ ((format (gnu_printf, 2, 3)));;
bool FTL_DB_avail(void) __attribute__ ((pure));
bool dbopen(void);
void dbclose(void);
int db_query_int(const char*);
long get_lastID(void);
#define dbopen(create) _dbopen(create, __FUNCTION__, __LINE__, __FILE__)
sqlite3 *_dbopen(bool create, const char *func, const int line, const char *file) __attribute__((warn_unused_result));
#define dbclose(db) _dbclose(db, __FUNCTION__, __LINE__, __FILE__)
void _dbclose(sqlite3 **db, const char *func, const int line, const char *file);
int db_query_int(sqlite3 *db, const char *querystr);
void SQLite3LogCallback(void *pArg, int iErrCode, const char *zMsg);
long int get_max_query_ID(void);
bool db_set_counter(const enum counters_table_props ID, const int value);
bool db_update_counters(const int total, const int blocked);
long int get_max_query_ID(sqlite3 *db);
bool db_update_counters(sqlite3 *db, const int total, const int blocked);
const char *get_sqlite3_version(void);
extern sqlite3 *FTL_db;
extern long int lastdbindex;
extern bool DBdeleteoldqueries;
// Database macros
#define SQL_bool(sql) {\
#define SQL_bool(db, ...) {\
int ret;\
if((ret = dbquery(sql)) != SQLITE_OK) {\
if((ret = dbquery(db, __VA_ARGS__)) != SQLITE_OK) {\
if(ret == SQLITE_BUSY)\
logg("WARNING: Database busy in %s()!", __FUNCTION__);\
else\
@ -59,9 +59,9 @@ extern bool DBdeleteoldqueries;
}\
}
#define SQL_void(sql) {\
#define SQL_void(db, ...) {\
int ret;\
if((ret = dbquery(sql)) != SQLITE_OK) {\
if((ret = dbquery(db, __VA_ARGS__)) != SQLITE_OK) {\
if(ret == SQLITE_BUSY)\
logg("WARNING: Database busy in %s()!", __FUNCTION__);\
else\

View File

@ -39,44 +39,48 @@ void *DB_thread(void *val)
// Run as long as this thread is not canceled
while(true)
{
if(FTL_DB_avail())
sqlite3 *db = dbopen(false);
if(db == NULL)
{
time_t now = time(NULL);
if(now - lastDBsave >= config.DBinterval)
// Sleep 5 seconds and try again
sleepms(5000);
continue;
}
time_t now = time(NULL);
if(now - lastDBsave >= config.DBinterval)
{
// Update lastDBsave timer
lastDBsave = time(NULL) - time(NULL)%config.DBinterval;
// Save data to database (if enabled)
if(config.DBexport)
{
// Update lastDBsave timer
lastDBsave = time(NULL) - time(NULL)%config.DBinterval;
lock_shm();
DB_save_queries(db);
unlock_shm();
// Save data to database (if enabled)
if(config.DBexport)
// Check if GC should be done on the database
if(DBdeleteoldqueries && config.maxDBdays != -1)
{
lock_shm();
DB_save_queries();
unlock_shm();
// Check if GC should be done on the database
if(DBdeleteoldqueries && config.maxDBdays != -1)
{
// No thread locks needed
delete_old_queries_in_DB();
DBdeleteoldqueries = false;
}
// No thread locks needed
delete_old_queries_in_DB(db);
DBdeleteoldqueries = false;
}
// Parse neighbor cache (fill network table) if enabled
if (config.parse_arp_cache)
set_event(PARSE_NEIGHBOR_CACHE);
}
// Update MAC vendor strings once a month (the MAC vendor
// database is not updated very often)
if(now % 2592000L == 0)
updateMACVendorRecords();
if(get_and_clear_event(PARSE_NEIGHBOR_CACHE))
parse_neighbor_cache();
// Parse neighbor cache (fill network table) if enabled
if (config.parse_arp_cache)
set_event(PARSE_NEIGHBOR_CACHE);
}
// Update MAC vendor strings once a month (the MAC vendor
// database is not updated very often)
if(now % 2592000L == 0)
updateMACVendorRecords(db);
if(get_and_clear_event(PARSE_NEIGHBOR_CACHE))
parse_neighbor_cache(db);
// Process database related event queue elements
if(get_and_clear_event(RELOAD_GRAVITY))
FTL_reload_all_domainlists();
@ -89,12 +93,15 @@ void *DB_thread(void *val)
if(get_and_clear_event(REIMPORT_ALIASCLIENTS))
{
lock_shm();
reimport_aliasclients();
reimport_aliasclients(db);
unlock_shm();
}
// Sleep 0.1 seconds
sleepms(100);
// Close database connection
dbclose(&db);
// Sleep 1 second
sleepms(1000);
}
return NULL;

View File

@ -364,7 +364,7 @@ static bool get_client_groupids(clientsData* client)
logg("Querying gravity database for MAC address of %s...", ip);
// Do the lookup
hwaddr = getMACfromIP(ip);
hwaddr = getMACfromIP(NULL, ip);
if(hwaddr == NULL && config.debug & DEBUG_CLIENTS)
{
@ -480,7 +480,7 @@ static bool get_client_groupids(clientsData* client)
logg("Querying gravity database for host name of %s...", ip);
// Do the lookup
hostname = getNameFromIP(ip);
hostname = getNameFromIP(NULL, ip);
if(hostname == NULL && config.debug & DEBUG_CLIENTS)
logg("--> No result.");
@ -566,7 +566,7 @@ static bool get_client_groupids(clientsData* client)
logg("Querying gravity database for interface of %s...", ip);
// Do the lookup
interface = getIfaceFromIP(ip);
interface = getIfaceFromIP(NULL, ip);
if(interface == NULL && config.debug & DEBUG_CLIENTS)
logg("--> No result.");

View File

@ -55,21 +55,21 @@ static unsigned char message_blob_types[MAX_MESSAGE][5] =
},
};
// Create message table in the database
bool create_message_table(void)
bool create_message_table(sqlite3 *db)
{
// The blob fields can hold arbitrary data. Their type is specified through the type.
SQL_bool("CREATE TABLE message ( id INTEGER PRIMARY KEY AUTOINCREMENT, "
"timestamp INTEGER NOT NULL, "
"type TEXT NOT NULL, "
"message TEXT NOT NULL, "
"blob1 BLOB, "
"blob2 BLOB, "
"blob3 BLOB, "
"blob4 BLOB, "
"blob5 BLOB );");
SQL_bool(db, "CREATE TABLE message ( id INTEGER PRIMARY KEY AUTOINCREMENT, "
"timestamp INTEGER NOT NULL, "
"type TEXT NOT NULL, "
"message TEXT NOT NULL, "
"blob1 BLOB, "
"blob2 BLOB, "
"blob3 BLOB, "
"blob4 BLOB, "
"blob5 BLOB );");
// Update database version to 6
if(!db_set_FTL_property(DB_VERSION, 6))
if(!db_set_FTL_property(db, DB_VERSION, 6))
{
logg("create_message_table(): Failed to update database version!");
return false;
@ -81,17 +81,31 @@ bool create_message_table(void)
// Flush message table
bool flush_message_table(void)
{
sqlite3 *db;
// Open database connection
if((db = dbopen(false)) == NULL)
{
logg("flush_message_table() - Failed to open DB");
return false;
}
// Flush message table
SQL_bool("DELETE FROM message;");
SQL_bool(db, "DELETE FROM message;");
// Close database connection
dbclose(&db);
return true;
}
static bool add_message(enum message_type type, const char *message,
const int count,...)
static bool add_message(enum message_type type,
const char *message, const int count,...)
{
if(!FTL_DB_avail())
sqlite3 *db;
// Open database connection
if((db = dbopen(false)) == NULL)
{
logg("flush_message_table() - Failed to open DB");
return false;
}
@ -100,11 +114,11 @@ static bool add_message(enum message_type type, const char *message,
{
sqlite3_stmt* stmt = NULL;
const char *querystr = "DELETE FROM message WHERE type = ?1 AND message = ?2";
int rc = sqlite3_prepare_v2(FTL_db, querystr, -1, &stmt, NULL);
int rc = sqlite3_prepare_v2(db, querystr, -1, &stmt, NULL);
if( rc != SQLITE_OK ){
logg("add_message(type=%u, message=%s) - SQL error prepare DELETE: %s",
type, message, sqlite3_errstr(rc));
dbclose();
type, message, sqlite3_errstr(rc));
dbclose(&db);
return false;
}
@ -112,10 +126,10 @@ static bool add_message(enum message_type type, const char *message,
if((rc = sqlite3_bind_text(stmt, 1, message_types[type], -1, SQLITE_STATIC)) != SQLITE_OK)
{
logg("add_message(type=%u, message=%s) - Failed to bind type DELETE: %s",
type, message, sqlite3_errstr(rc));
type, message, sqlite3_errstr(rc));
sqlite3_reset(stmt);
sqlite3_finalize(stmt);
dbclose();
dbclose(&db);
return false;
}
@ -123,10 +137,10 @@ static bool add_message(enum message_type type, const char *message,
if((rc = sqlite3_bind_text(stmt, 2, message, -1, SQLITE_STATIC)) != SQLITE_OK)
{
logg("add_message(type=%u, message=%s) - Failed to bind message DELETE: %s",
type, message, sqlite3_errstr(rc));
type, message, sqlite3_errstr(rc));
sqlite3_reset(stmt);
sqlite3_finalize(stmt);
dbclose();
dbclose(&db);
return false;
}
@ -134,8 +148,8 @@ static bool add_message(enum message_type type, const char *message,
if((rc = sqlite3_step(stmt)) != SQLITE_OK && rc != SQLITE_DONE)
{
logg("add_message(type=%u, message=%s) - SQL error step DELETE: %s",
type, message, sqlite3_errstr(rc));
dbclose();
type, message, sqlite3_errstr(rc));
dbclose(&db);
return false;
}
sqlite3_clear_bindings(stmt);
@ -147,12 +161,12 @@ static bool add_message(enum message_type type, const char *message,
sqlite3_stmt* stmt = NULL;
const char *querystr = "INSERT INTO message (timestamp,type,message,blob1,blob2,blob3,blob4,blob5) "
"VALUES ((cast(strftime('%s', 'now') as int)),?,?,?,?,?,?,?);";
int rc = sqlite3_prepare_v2(FTL_db, querystr, -1, &stmt, NULL);
int rc = sqlite3_prepare_v2(db, querystr, -1, &stmt, NULL);
if( rc != SQLITE_OK )
{
logg("add_message(type=%u, message=%s) - SQL error prepare: %s",
type, message, sqlite3_errstr(rc));
dbclose();
dbclose(&db);
return false;
}
@ -163,7 +177,7 @@ static bool add_message(enum message_type type, const char *message,
type, message, sqlite3_errstr(rc));
sqlite3_reset(stmt);
sqlite3_finalize(stmt);
dbclose();
dbclose(&db);
return false;
}
@ -174,7 +188,7 @@ static bool add_message(enum message_type type, const char *message,
type, message, sqlite3_errstr(rc));
sqlite3_reset(stmt);
sqlite3_finalize(stmt);
dbclose();
dbclose(&db);
return false;
}
@ -206,7 +220,7 @@ static bool add_message(enum message_type type, const char *message,
type, message, 3 + j, datatype, sqlite3_errstr(rc));
sqlite3_reset(stmt);
sqlite3_finalize(stmt);
dbclose();
dbclose(&db);
return false;
}
}
@ -221,10 +235,13 @@ static bool add_message(enum message_type type, const char *message,
if(rc != SQLITE_DONE)
{
logg("Encountered error while trying to store message in long-term database: %s", sqlite3_errstr(rc));
dbclose();
dbclose(&db);
return false;
}
// Close database connection
dbclose(&db);
return true;
}
@ -270,8 +287,7 @@ void logg_fatal_dnsmasq_message(const char *message)
// Log to pihole-FTL.log
logg("FATAL ERROR in dnsmasq core: %s", message);
// Log to database (we have to open the database at this point)
dbopen();
// Log to database
add_message(DNSMASQ_CONFIG_MESSAGE, message, 0);
// FTL will dies after this point, so we should make sure to clean up

View File

@ -10,7 +10,9 @@
#ifndef MESSAGETABLE_H
#define MESSAGETABLE_H
bool create_message_table(void);
#include "sqlite3.h"
bool create_message_table(sqlite3 *db);
bool flush_message_table(void);
void logg_regex_warning(const char *type, const char *warning, const int dbindex, const char *regex);
void logg_subnet_warning(const char *ip, const int matching_count, const char *matching_ids,

File diff suppressed because it is too large Load Diff

View File

@ -10,17 +10,19 @@
#ifndef NETWORKTABLE_H
#define NETWORKTABLE_H
bool create_network_table(void);
bool create_network_addresses_table(void);
bool create_network_addresses_with_names_table(void);
void parse_neighbor_cache(void);
void updateMACVendorRecords(void);
bool unify_hwaddr(void);
#include "sqlite3.h"
bool create_network_table(sqlite3 *db);
bool create_network_addresses_table(sqlite3 *db);
bool create_network_addresses_with_names_table(sqlite3 *db);
void parse_neighbor_cache(sqlite3 *db);
void updateMACVendorRecords(sqlite3 *db);
bool unify_hwaddr(sqlite3 *db);
char* getDatabaseHostname(const char* ipaddr) __attribute__((malloc));
char* __attribute__((malloc)) getMACfromIP(const char* ipaddr);
int getAliasclientIDfromIP(const char *ipaddr);
char* __attribute__((malloc)) getNameFromIP(const char* ipaddr);
char* __attribute__((malloc)) getIfaceFromIP(const char* ipaddr);
char* __attribute__((malloc)) getMACfromIP(sqlite3 *db, const char* ipaddr);
int getAliasclientIDfromIP(sqlite3 *db, const char *ipaddr);
char* __attribute__((malloc)) getNameFromIP(sqlite3 *db, const char* ipaddr);
char* __attribute__((malloc)) getIfaceFromIP(sqlite3 *db, const char* ipaddr);
void resolveNetworkTableNames(void);
#endif //NETWORKTABLE_H

View File

@ -28,53 +28,71 @@
static bool saving_failed_before = false;
int get_number_of_queries_in_DB(void)
int get_number_of_queries_in_DB(sqlite3 *db)
{
// This routine is used by the API routines.
if(!FTL_DB_avail())
// Open pihole-FTL.db database file if needed
bool db_opened = false;
if(db == NULL)
{
return DB_FAILED;
if((db = dbopen(false)) == NULL)
{
logg("get_number_of_queries_in_DB() - Failed to open DB");
return -1;
}
// Successful
db_opened = true;
}
// Count number of rows using the index timestamp is faster than select(*)
int result = db_query_int("SELECT COUNT(timestamp) FROM queries");
int result = db_query_int(db, "SELECT COUNT(timestamp) FROM queries");
if(db_opened)
dbclose(&db);
return result;
}
bool DB_save_queries(void)
bool DB_save_queries(sqlite3 *db)
{
// The database may be unavailable, e.g. when disabled
if(!FTL_DB_avail())
{
return false;
}
// Start database timer
if(config.debug & DEBUG_DATABASE)
timer_start(DATABASE_WRITE_TIMER);
// Open pihole-FTL.db database file if needed
bool db_opened = false;
if(db == NULL)
{
if((db = dbopen(false)) == NULL)
{
logg("DB_save_queries() - Failed to open DB");
return NULL;
}
// Successful
db_opened = true;
}
unsigned int saved = 0;
bool error = false;
sqlite3_stmt* stmt = NULL;
int rc = dbquery("BEGIN TRANSACTION IMMEDIATE");
int rc = dbquery(db, "BEGIN TRANSACTION IMMEDIATE");
if( rc != SQLITE_OK )
{
const char *text;
if( rc == SQLITE_BUSY )
text = "WARNING";
else
{
text = "ERROR";
dbclose();
}
logg("%s: Storing queries in long-term database failed: %s", text, sqlite3_errstr(rc));
if(db_opened)
dbclose(&db);
return false;
}
rc = sqlite3_prepare_v2(FTL_db, "INSERT INTO queries VALUES (NULL,?,?,?,?,?,?,?)", -1, &stmt, NULL);
rc = sqlite3_prepare_v2(db, "INSERT INTO queries VALUES (NULL,?,?,?,?,?,?,?)", -1, &stmt, NULL);
if( rc != SQLITE_OK )
{
const char *text, *spaces;
@ -87,18 +105,19 @@ bool DB_save_queries(void)
{
text = "ERROR";
spaces = " ";
dbclose();
}
// dbquery() above already logs the reson for why the query failed
logg("%s: Storing queries in long-term database failed: %s\n", text, sqlite3_errstr(rc));
logg("%s Keeping queries in memory for later new attempt", spaces);
saving_failed_before = true;
if(db_opened)
dbclose(&db);
return false;
}
// Get last ID stored in the database
long int lastID = get_max_query_ID();
long int lastID = get_max_query_ID(db);
int total = 0, blocked = 0;
time_t currenttimestamp = time(NULL);
@ -233,14 +252,15 @@ bool DB_save_queries(void)
logg("Keeping queries in memory for later new attempt");
saving_failed_before = true;
}
else
dbclose();
if(db_opened)
dbclose(&db);
return false;
}
// Finish prepared statement
if((rc = dbquery("END TRANSACTION")) != SQLITE_OK)
if((rc = dbquery(db,"END TRANSACTION")) != SQLITE_OK)
{
// No need to log the error string here, dbquery() did that already above
logg("END TRANSACTION failed when trying to store queries to long-term database");
@ -250,8 +270,9 @@ bool DB_save_queries(void)
logg("Keeping queries in memory for later new attempt");
saving_failed_before = true;
}
else
dbclose();
if(db_opened)
dbclose(&db);
return false;
}
@ -261,13 +282,14 @@ bool DB_save_queries(void)
if(saved > 0 && !error)
{
lastdbindex = queryID;
db_set_FTL_property(DB_LASTTIMESTAMP, newlasttimestamp);
db_update_counters(total, blocked);
db_set_FTL_property(db, DB_LASTTIMESTAMP, newlasttimestamp);
db_update_counters(db, total, blocked);
}
if(config.debug & DEBUG_DATABASE || saving_failed_before)
{
logg("Notice: Queries stored in long-term database: %u (took %.1f ms, last SQLite ID %li)", saved, timer_elapsed_msec(DATABASE_WRITE_TIMER), lastID);
logg("Notice: Queries stored in long-term database: %u (took %.1f ms, last SQLite ID %li)",
saved, timer_elapsed_msec(DATABASE_WRITE_TIMER), lastID);
if(saving_failed_before)
{
logg(" Queries from earlier attempt(s) stored successfully");
@ -275,27 +297,24 @@ bool DB_save_queries(void)
}
}
if(db_opened)
dbclose(&db);
return true;
}
void delete_old_queries_in_DB(void)
void delete_old_queries_in_DB(sqlite3 *db)
{
// Open database
if(!FTL_DB_avail())
{
return;
}
int timestamp = time(NULL) - config.maxDBdays * 86400;
if(dbquery("DELETE FROM queries WHERE timestamp <= %i", timestamp) != SQLITE_OK)
if(dbquery(db, "DELETE FROM queries WHERE timestamp <= %i", timestamp) != SQLITE_OK)
{
logg("delete_old_queries_in_DB(): Deleting queries due to age of entries failed!");
return;
}
// Get how many rows have been affected (deleted)
const int affected = sqlite3_changes(FTL_db);
const int affected = sqlite3_changes(db);
// Print final message only if there is a difference
if((config.debug & DEBUG_DATABASE) || affected)
@ -306,8 +325,12 @@ void delete_old_queries_in_DB(void)
void DB_read_queries(void)
{
// Open database
if(!dbopen())
sqlite3 *db;
if((db = dbopen(false)) == NULL)
{
logg("DB_read_queries() - Failed to open DB");
return;
}
// Prepare request
// Get time stamp 24 hours in the past
@ -320,10 +343,10 @@ void DB_read_queries(void)
// Prepare SQLite3 statement
sqlite3_stmt* stmt = NULL;
int rc = sqlite3_prepare_v2(FTL_db, querystr, -1, &stmt, NULL);
int rc = sqlite3_prepare_v2(db, querystr, -1, &stmt, NULL);
if( rc != SQLITE_OK ){
logg("DB_read_queries() - SQL error prepare: %s", sqlite3_errstr(rc));
dbclose();
dbclose(&db);
return;
}
@ -331,7 +354,7 @@ void DB_read_queries(void)
if((rc = sqlite3_bind_int(stmt, 1, mintime)) != SQLITE_OK)
{
logg("DB_read_queries() - Failed to bind type mintime: %s", sqlite3_errstr(rc));
dbclose();
dbclose(&db);
return;
}
@ -343,12 +366,12 @@ void DB_read_queries(void)
// 1483228800 = 01/01/2017 @ 12:00am (UTC)
if(queryTimeStamp < 1483228800)
{
logg("FTL_db warn: TIMESTAMP should be larger than 01/01/2017 but is %lli", (long long)queryTimeStamp);
logg("DB warn: TIMESTAMP should be larger than 01/01/2017 but is %lli", (long long)queryTimeStamp);
continue;
}
if(queryTimeStamp > now)
{
if(config.debug & DEBUG_DATABASE) logg("FTL_db warn: Skipping query logged in the future (%lli)", (long long)queryTimeStamp);
if(config.debug & DEBUG_DATABASE) logg("DB warn: Skipping query logged in the future (%lli)", (long long)queryTimeStamp);
continue;
}
@ -357,7 +380,7 @@ void DB_read_queries(void)
const bool offset_type = type > 100 && type < (100 + UINT16_MAX);
if(!mapped_type && !offset_type)
{
logg("FTL_db warn: TYPE should not be %i", type);
logg("DB warn: TYPE should not be %i", type);
continue;
}
// Don't import AAAA queries from database if the user set
@ -370,7 +393,7 @@ void DB_read_queries(void)
const int status_int = sqlite3_column_int(stmt, 3);
if(status_int < QUERY_UNKNOWN || status_int >= QUERY_STATUS_MAX)
{
logg("FTL_db warn: STATUS should be within [%i,%i] but is %i", QUERY_UNKNOWN, QUERY_STATUS_MAX-1, status_int);
logg("DB warn: STATUS should be within [%i,%i] but is %i", QUERY_UNKNOWN, QUERY_STATUS_MAX-1, status_int);
continue;
}
const enum query_status status = status_int;
@ -378,14 +401,14 @@ void DB_read_queries(void)
const char * domainname = (const char *)sqlite3_column_text(stmt, 4);
if(domainname == NULL)
{
logg("FTL_db warn: DOMAIN should never be NULL, %lli", (long long)queryTimeStamp);
logg("DB warn: DOMAIN should never be NULL, %lli", (long long)queryTimeStamp);
continue;
}
const char * clientIP = (const char *)sqlite3_column_text(stmt, 5);
if(clientIP == NULL)
{
logg("FTL_db warn: CLIENT should never be NULL, %lli", (long long)queryTimeStamp);
logg("DB warn: CLIENT should never be NULL, %lli", (long long)queryTimeStamp);
continue;
}
@ -574,7 +597,7 @@ void DB_read_queries(void)
if( rc != SQLITE_DONE ){
logg("DB_read_queries() - SQL error step: %s", sqlite3_errstr(rc));
dbclose();
dbclose(&db);
return;
}
@ -582,5 +605,5 @@ void DB_read_queries(void)
sqlite3_finalize(stmt);
// Close database here, we have to reopen it later (after forking)
dbclose();
dbclose(&db);
}

View File

@ -10,9 +10,11 @@
#ifndef DATABASE_QUERY_TABLE_H
#define DATABASE_QUERY_TABLE_H
int get_number_of_queries_in_DB(void);
void delete_old_queries_in_DB(void);
bool DB_save_queries(void);
#include "sqlite3.h"
int get_number_of_queries_in_DB(sqlite3 *db);
void delete_old_queries_in_DB(sqlite3 *db);
bool DB_save_queries(sqlite3 *db);
void DB_read_queries(void);
#endif //DATABASE_QUERY_TABLE_H

View File

@ -269,7 +269,7 @@ int findClientID(const char *clientIP, const bool count, const bool aliasclient)
// Check if this client is managed by a alias-client
if(!aliasclient)
reset_aliasclient(client);
reset_aliasclient(NULL, client);
return clientID;
}

View File

@ -25,8 +25,6 @@
// logg_fatal_dnsmasq_message()
#include "database/message-table.h"
static FILE *logfile = NULL;
static bool FTL_log_ready = false;
static bool print_log = true, print_stdout = true;
void log_ctrl(bool plog, bool pstdout)
@ -35,23 +33,14 @@ void log_ctrl(bool plog, bool pstdout)
print_stdout = pstdout;
}
static void close_FTL_log(void)
void init_FTL_log(void)
{
if(logfile != NULL)
fclose(logfile);
}
void open_FTL_log(const bool init)
{
if(init)
{
// Obtain log file location
getLogFilePath();
}
// Obtain log file location
getLogFilePath();
// Open the log file in append/create mode
logfile = fopen(FTLfiles.log, "a+");
if((logfile == NULL) && init){
FILE *logfile = fopen(FTLfiles.log, "a+");
if((logfile == NULL)){
syslog(LOG_ERR, "Opening of FTL\'s log file failed!");
printf("FATAL: Opening of FTL log (%s) failed!\n",FTLfiles.log);
printf(" Make sure it exists and is writeable by user %s\n", username);
@ -59,13 +48,7 @@ void open_FTL_log(const bool init)
exit(EXIT_FAILURE);
}
// Set log as ready (we were able to open it)
FTL_log_ready = true;
if(init)
{
close_FTL_log();
}
fclose(logfile);
}
// The size of 84 bytes has been carefully selected for all possible timestamps
@ -140,10 +123,10 @@ void _FTL_log(const bool newline, const char *format, ...)
printf("\n");
}
if(print_log && FTL_log_ready)
if(print_log)
{
// Open log file
open_FTL_log(false);
FILE *logfile = fopen(FTLfiles.log, "a+");
// Write to log file
if(logfile != NULL)
@ -153,15 +136,14 @@ void _FTL_log(const bool newline, const char *format, ...)
vfprintf(logfile, format, args);
va_end(args);
fputc('\n',logfile);
fclose(logfile);
}
else if(!daemonmode)
{
printf("!!! WARNING: Writing to FTL\'s log file failed!\n");
syslog(LOG_ERR, "Writing to FTL\'s log file failed!");
}
// Close log file
close_FTL_log();
}
}

View File

@ -14,7 +14,6 @@
#include <time.h>
void init_FTL_log(void);
void open_FTL_log(const bool init);
void log_counter_info(void);
void format_memory_size(char * const prefix, unsigned long long int bytes,
double * const formated);

View File

@ -45,7 +45,7 @@ int main (int argc, char* argv[])
parse_args(argc, argv);
// Try to open FTL log
open_FTL_log(true);
init_FTL_log();
timer_start(EXIT_TIMER);
logg("########## FTL started! ##########");
log_FTL_version(false);
@ -103,7 +103,7 @@ int main (int argc, char* argv[])
// Save new queries to database (if database is used)
if(config.DBexport)
{
if(DB_save_queries())
if(DB_save_queries(NULL))
logg("Finished final database update");
}

View File

@ -323,7 +323,7 @@ static size_t resolveAndAddHostname(size_t ippos, size_t oldnamepos)
if(strlen(newname) == 0 && config.names_from_netdb)
{
free(newname);
newname = getNameFromIP(ipaddr);
newname = getNameFromIP(NULL, ipaddr);
}
// Only store new newname if it is valid and differs from oldname