diff --git a/src/config/legacy_reader.c b/src/config/legacy_reader.c index 9f2bdfb6..17ed72bd 100644 --- a/src/config/legacy_reader.c +++ b/src/config/legacy_reader.c @@ -837,7 +837,7 @@ static void readDebugingSettingsLegacy(FILE *fp) // Parse debug options set_debug_flags(); - if(debug_any) + if(debug_flags[DEBUG_ANY]) { // Enable debug logging in dnsmasq (only effective before starting the resolver) argv_dnsmasq[2] = "--log-debug"; diff --git a/src/database/common.c b/src/database/common.c index 44048652..ad520e02 100644 --- a/src/database/common.c +++ b/src/database/common.c @@ -8,24 +8,26 @@ * This file is copyright under the latest version of the EUPL. * Please see LICENSE file for your rights under this license. */ -#include "../FTL.h" -#include "common.h" -#include "network-table.h" -#include "message-table.h" -#include "../shmem.h" +#include "FTL.h" +#include "database/common.h" +#include "database/network-table.h" +#include "database/message-table.h" +#include "shmem.h" // struct config -#include "../config/config.h" +#include "config/config.h" // logging routines -#include "../log.h" -#include "../timers.h" +#include "log.h" +#include "timers.h" // file_exists() -#include "../files.h" -#include "sqlite3-ext.h" +#include "files.h" +#include "database/sqlite3-ext.h" // import_aliasclients() -#include "aliasclients.h" +#include "database/aliasclients.h" // CREATE_QUERIES_TABLE // add_additional_info_column() -#include "query-table.h" +#include "database/query-table.h" +// set_event() +#include "events.h" bool DBdeleteoldqueries = false; static bool DBerror = false; diff --git a/src/database/database-thread.c b/src/database/database-thread.c index 964c335c..56d8e1d6 100644 --- a/src/database/database-thread.c +++ b/src/database/database-thread.c @@ -9,25 +9,27 @@ * Please see LICENSE file for your rights under this license. */ #include "FTL.h" -#include "database-thread.h" -#include "common.h" +#include "database/database-thread.h" +#include "database/common.h" // [un]lock_shm(); #include "shmem.h" // parse_neighbor_cache() -#include "network-table.h" +#include "database/network-table.h" // export_queries_to_disk() -#include "query-table.h" +#include "database/query-table.h" #include "config/config.h" #include "log.h" #include "timers.h" // global variable killed #include "signals.h" // reimport_aliasclients() -#include "aliasclients.h" +#include "database/aliasclients.h" // Eventqueue routines #include "events.h" // get_FTL_db_filesize() #include "files.h" +// gravity_updated() +#include "database/gravity-db.h" #define TIME_T "%li" @@ -137,6 +139,13 @@ void *DB_thread(void *val) if(killed) break; + // Check if we need to reload gravity + if(gravity_updated()) + { + // Reload gravity + set_event(RELOAD_GRAVITY); + } + // Parse ARP cache if requested if(get_and_clear_event(PARSE_NEIGHBOR_CACHE)) { diff --git a/src/database/gravity-db.c b/src/database/gravity-db.c index 511f3c9c..43e07f98 100644 --- a/src/database/gravity-db.c +++ b/src/database/gravity-db.c @@ -233,7 +233,6 @@ static inline const char *show_client_string(const char *hwaddr, const char *hos return ip; } - // Get associated groups for this client (if defined) static bool get_client_groupids(clientsData* client) { @@ -2356,3 +2355,66 @@ void check_inaccessible_adlists(void) // Finalize statement sqlite3_finalize(query_stmt); } + +static sqlite3_int64 last_updated = -1; +bool gravity_updated(void) +{ + bool changed = false; + sqlite3 *db = NULL; + sqlite3_stmt *query_stmt = NULL; + + // Open database + int rc = sqlite3_open_v2(config.files.gravity.v.s, &db, SQLITE_OPEN_READONLY, NULL); + if(db == NULL) + { + log_err("gravity_updated(): %s - SQL error open: %s", config.files.gravity.v.s, sqlite3_errstr(rc)); + return false; + } + + // Get *updated* timestamp from gravity database + const char *querystr = "SELECT value FROM info WHERE property = 'updated';"; + rc = sqlite3_prepare_v2(db, querystr, -1, &query_stmt, NULL); + if(rc != SQLITE_OK){ + // Ignore SQLITE_BUSY errors, as this is not a critical error + // We will just try again later + if(rc != SQLITE_BUSY) + log_warn("gravity_updated(): %s - SQL error prepare: %s", querystr, sqlite3_errstr(rc)); + sqlite3_close(db); + return false; + } + + // Perform query + rc = sqlite3_step(query_stmt); + if(rc != SQLITE_ROW) + { + log_err("gravity_updated(): %s - SQL error step: %s", querystr, sqlite3_errstr(rc)); + sqlite3_finalize(query_stmt); + sqlite3_close(db); + return false; + } + + // Get timestamp from database + const sqlite3_int64 updated = sqlite3_column_int64(query_stmt, 0); + + // Check if timestamp has changed + if(last_updated == -1) + { + // First run, set last_updated + last_updated = updated; + } + else if(last_updated < updated) + { + // Gravity database has been updated + last_updated = updated; + changed = true; + log_info("Gravity database has been updated, reloading now"); + } + + // Finalize statement + sqlite3_finalize(query_stmt); + + // Close database + sqlite3_close(db); + + return changed; +} \ No newline at end of file diff --git a/src/database/gravity-db.h b/src/database/gravity-db.h index 7f94afd1..00f34cbd 100644 --- a/src/database/gravity-db.h +++ b/src/database/gravity-db.h @@ -51,6 +51,7 @@ char* get_client_names_from_ids(const char *group_ids) __attribute__ ((malloc)); void gravityDB_finalizeTable(void); int gravityDB_count(const enum gravity_tables list); void check_inaccessible_adlists(void); +bool gravity_updated(void); enum db_result in_gravity(const char *domain, clientsData *client); enum db_result in_denylist(const char *domain, DNSCacheData *dns_cache, clientsData *client); diff --git a/src/log.c b/src/log.c index 26773ce7..e1122ae2 100644 --- a/src/log.c +++ b/src/log.c @@ -27,7 +27,6 @@ static bool print_log = true, print_stdout = true; static const char *process = ""; -bool debug_any = false; bool debug_flags[DEBUG_MAX] = { false }; // Set debug flags from config struct to global debug_flags array @@ -36,7 +35,6 @@ bool debug_flags[DEBUG_MAX] = { false }; void set_debug_flags(void) { // Reset debug flags - debug_any = false; memset(debug_flags, false, sizeof(debug_flags)); // Loop over all debug options and check if at least one is enabled @@ -47,7 +45,7 @@ void set_debug_flags(void) { // Add offset of 1 as the first element is "ANY" debug_flags[i + 1] = true; - debug_any = true; + debug_flags[DEBUG_ANY] = true; } } } diff --git a/src/log.h b/src/log.h index db27492c..13599dc0 100644 --- a/src/log.h +++ b/src/log.h @@ -37,7 +37,6 @@ #define CONFIG_CENTER(fp, width, fmt, ...) \ FPRINTF_CENTER(fp, width, "#", fmt , "#\n", __VA_ARGS__) -extern bool debug_any; extern bool debug_flags[DEBUG_MAX]; void set_debug_flags(void); @@ -66,7 +65,7 @@ void dnsmasq_diagnosis_warning(char *message); #define log_notice(format, ...) _FTL_log(LOG_NOTICE, 0, format, ## __VA_ARGS__) #define log_info(format, ...) _FTL_log(LOG_INFO, 0, format, ## __VA_ARGS__) #define log_debug(flag, format, ...)({ \ - if((flag == DEBUG_ANY && debug_any) || (flag < DEBUG_MAX && debug_flags[flag])) \ + if(flag > -1 && flag < DEBUG_MAX && debug_flags[flag]) \ _FTL_log(LOG_DEBUG, flag, format, ## __VA_ARGS__); \ }) void _FTL_log(const int priority, const enum debug_flag flag, const char *format, ...) __attribute__ ((format (gnu_printf, 3, 4))); diff --git a/src/shmem.c b/src/shmem.c index f7a26189..04377726 100644 --- a/src/shmem.c +++ b/src/shmem.c @@ -1056,7 +1056,7 @@ static inline bool check_range(int ID, int MAXID, const char* type, const char * // Check bounds if(ID < 0 || ID > MAXID) { - if(debug_any) + if(debug_flags[DEBUG_ANY]) { log_err("Trying to access %s ID %i, but maximum is %i", type, ID, MAXID); log_err("found in %s() (%s:%i)", func, short_path(file), line); @@ -1073,7 +1073,7 @@ static inline bool check_magic(int ID, bool checkMagic, unsigned char magic, con // Check magic only if requested (skipped for new entries which are uninitialized) if(checkMagic && magic != MAGICBYTE) { - if(debug_any) + if(debug_flags[DEBUG_ANY]) { log_err("Trying to access %s ID %i, but magic byte is %x", type, ID, magic); log_err("found in %s() (%s:%i)", func, short_path(file), line); @@ -1094,7 +1094,7 @@ queriesData* _getQuery(int queryID, bool checkMagic, int line, const char *func, // We are not in a locked situation, return a NULL pointer if(config.debug.locks.v.b && !is_our_lock()) { - if(debug_any) + if(debug_flags[DEBUG_ANY]) { log_err("Tried to obtain query pointer without lock in %s() (%s:%i)!", func, short_path(file), line); @@ -1119,7 +1119,7 @@ clientsData* _getClient(int clientID, bool checkMagic, int line, const char *fun // We are not in a locked situation, return a NULL pointer if(config.debug.locks.v.b && !is_our_lock()) { - if(debug_any) + if(debug_flags[DEBUG_ANY]) { log_err("Tried to obtain client pointer without lock in %s() (%s:%i)!", func, short_path(file), line); @@ -1144,7 +1144,7 @@ domainsData* _getDomain(int domainID, bool checkMagic, int line, const char *fun // We are not in a locked situation, return a NULL pointer if(config.debug.locks.v.b && !is_our_lock()) { - if(debug_any) + if(debug_flags[DEBUG_ANY]) { log_err("Tried to obtain domain pointer without lock in %s() (%s:%i)!", func, short_path(file), line); @@ -1169,7 +1169,7 @@ upstreamsData* _getUpstream(int upstreamID, bool checkMagic, int line, const cha // We are not in a locked situation, return a NULL pointer if(config.debug.locks.v.b && !is_our_lock()) { - if(debug_any) + if(debug_flags[DEBUG_ANY]) { log_err("Tried to obtain upstream pointer without lock in %s() (%s:%i)!", func, short_path(file), line); @@ -1194,7 +1194,7 @@ DNSCacheData* _getDNSCache(int cacheID, bool checkMagic, int line, const char *f // We are not in a locked situation, return a NULL pointer if(config.debug.locks.v.b && !is_our_lock()) { - if(debug_any) + if(debug_flags[DEBUG_ANY]) { log_err("Tried to obtain cache pointer without lock in %s() (%s:%i)!", func, short_path(file), line); diff --git a/test/gravity.db.sql b/test/gravity.db.sql index bbcc2b7a..cd7b5814 100644 --- a/test/gravity.db.sql +++ b/test/gravity.db.sql @@ -221,6 +221,7 @@ INSERT INTO gravity VALUES('gravity.ftl',1); INSERT INTO gravity VALUES('gravity-aaaa.ftl',1); INSERT INTO gravity VALUES('gravity-allowed.ftl',1); INSERT INTO info VALUES('gravity_count',4); +INSERT INTO info VALUES('updated',0); INSERT INTO "group" VALUES(1,0,'Test group',1559928803,1559928803,'A disabled test group'); INSERT INTO domainlist_by_group VALUES(15,1);