diff --git a/src/database/gravity-db.c b/src/database/gravity-db.c index 685b80f1..38388803 100644 --- a/src/database/gravity-db.c +++ b/src/database/gravity-db.c @@ -23,9 +23,9 @@ // SQLite3 prepared statement vectors #include "../vector.h" -// Process-private prepared statements are used to support -// multiple forks (might be TCP workers) to use the database -// simultaneously without corrupting the gravity database +// Process-private prepared statements are used to support multiple forks (might +// be TCP workers) to use the database simultaneously without corrupting the +// gravity database sqlite3_stmt_vec *whitelist_stmt = NULL; sqlite3_stmt_vec *gravity_stmt = NULL; sqlite3_stmt_vec *blacklist_stmt = NULL; @@ -46,9 +46,8 @@ void rehash(int size); // Initialize gravity subroutines static void gravityDB_check_fork(void) { - // Memorize main process PID on first call - // of this funtion (guaranteed to be the - // main dnsmasq thread) + // Memorize main process PID on first call of this funtion (guaranteed to be + // the main dnsmasq thread) if(main_process == 0) { main_process = getpid(); @@ -58,23 +57,19 @@ static void gravityDB_check_fork(void) if(this_process == getpid()) return; - // If we reach this point, FTL forked to handle - // TCP connections with dedicated (forked) workers - // SQLite3's mentions that carrying an open database - // connection across a fork() can lead to all kinds - // of locking problems as SQLite3 was not intended - // to work under such circumstances. Doing so may - // easily lead to ending up with a corrupted database. + // If we reach this point, FTL forked to handle TCP connections with + // dedicated (forked) workers SQLite3's mentions that carrying an open + // database connection across a fork() can lead to all kinds of locking + // problems as SQLite3 was not intended to work under such circumstances. + // Doing so may easily lead to ending up with a corrupted database. logg("Note: FTL forked to handle TCP requests"); - // Memorize PID of this thread to avoid re-opening the - // gravity database connection multiple times for the - // same fork + // Memorize PID of this thread to avoid re-opening the gravity database + // connection multiple times for the same fork this_process = getpid(); - // Pretend that we did not open the database so far - // so it needs to be re-opened, also pretend we have - // not yet prepared the list statements + // Pretend that we did not open the database so far so it needs to be + // re-opened, also pretend we have not yet prepared the list statements gravityDB_opened = false; gravity_db = NULL; whitelist_stmt = NULL; @@ -327,7 +322,6 @@ bool gravityDB_prepare_client_statements(const int clientID, clientsData *client // Get associated groups for this client (if defined) char *querystr = NULL; - sqlite3_stmt* prep_stmp = NULL; char *groups = NULL; if(!get_client_groupids(client, &groups)) return false; @@ -341,42 +335,43 @@ bool gravityDB_prepare_client_statements(const int clientID, clientsData *client if(config.debug & DEBUG_DATABASE) logg("gravityDB_open(): Preparing vw_whitelist statement for client %s", clientip); querystr = get_client_querystr("vw_whitelist", groups); - int rc = sqlite3_prepare_v2(gravity_db, querystr, -1, &prep_stmp, NULL); + sqlite3_stmt* stmt = NULL; + int rc = sqlite3_prepare_v2(gravity_db, querystr, -1, &stmt, NULL); if( rc != SQLITE_OK ) { logg("gravityDB_open(\"SELECT EXISTS(... vw_whitelist ...)\") - SQL error prepare: %s", sqlite3_errstr(rc)); gravityDB_close(); return false; } - whitelist_stmt->set(whitelist_stmt, clientID, prep_stmp); + whitelist_stmt->set(whitelist_stmt, clientID, stmt); free(querystr); // Prepare gravity statement if(config.debug & DEBUG_DATABASE) logg("gravityDB_open(): Preparing vw_gravity statement for client %s", clientip); querystr = get_client_querystr("vw_gravity", groups); - rc = sqlite3_prepare_v2(gravity_db, querystr, -1, &prep_stmp, NULL); + rc = sqlite3_prepare_v2(gravity_db, querystr, -1, &stmt, NULL); if( rc != SQLITE_OK ) { logg("gravityDB_open(\"SELECT EXISTS(... vw_gravity ...)\") - SQL error prepare: %s", sqlite3_errstr(rc)); gravityDB_close(); return false; } - gravity_stmt->set(gravity_stmt, clientID, prep_stmp); + gravity_stmt->set(gravity_stmt, clientID, stmt); free(querystr); // Prepare blacklist statement if(config.debug & DEBUG_DATABASE) logg("gravityDB_open(): Preparing vw_blacklist statement for client %s", clientip); querystr = get_client_querystr("vw_blacklist", groups); - rc = sqlite3_prepare_v2(gravity_db, querystr, -1, &prep_stmp, NULL); + rc = sqlite3_prepare_v2(gravity_db, querystr, -1, &stmt, NULL); if( rc != SQLITE_OK ) { logg("gravityDB_open(\"SELECT EXISTS(... vw_blacklist ...)\") - SQL error prepare: %s", sqlite3_errstr(rc)); gravityDB_close(); return false; } - blacklist_stmt->set(blacklist_stmt, clientID, prep_stmp); + blacklist_stmt->set(blacklist_stmt, clientID, stmt); free(querystr); // Free groups @@ -385,6 +380,7 @@ bool gravityDB_prepare_client_statements(const int clientID, clientsData *client return true; } +// Finalize non-NULL prepared statements and set them to NULL for a given client static inline void gravityDB_finalize_client_statements(const int clientID) { if(whitelist_stmt->get(whitelist_stmt, clientID) != NULL) @@ -404,6 +400,7 @@ static inline void gravityDB_finalize_client_statements(const int clientID) } } +// Close gravity database connection void gravityDB_close(void) { // Return early if gravity database is not available @@ -432,9 +429,8 @@ void gravityDB_close(void) gravityDB_opened = false; } -// Prepare a SQLite3 statement which can be used by -// gravityDB_getDomain() to get blocking domains from -// a table which is specified when calling this function +// Prepare a SQLite3 statement which can be used by gravityDB_getDomain() to get +// blocking domains from a table which is specified when calling this function bool gravityDB_getTable(const unsigned char list) { // First check if FTL forked to handle TCP connections @@ -646,15 +642,15 @@ static bool domain_in_list(const char *domain, sqlite3_stmt* stmt, const char* l if(config.debug & DEBUG_DATABASE) logg("domain_in_list(\"%s\", %p, %s): %d", domain, stmt, listname, result); - // The sqlite3_reset() function is called to reset a prepared - // statement object back to its initial state, ready to be - // re-executed. Note: Any SQL statement variables that had values - // bound to them using the sqlite3_bind_*() API retain their values. + // The sqlite3_reset() function is called to reset a prepared statement + // object back to its initial state, ready to be re-executed. Note: Any SQL + // statement variables that had values bound to them using the + // sqlite3_bind_*() API retain their values. sqlite3_reset(stmt); - // Contrary to the intuition of many, sqlite3_reset() does not reset - // the bindings on a prepared statement. Use this routine to reset - // all host parameters to NULL. + // Contrary to the intuition of many, sqlite3_reset() does not reset the + // bindings on a prepared statement. Use this routine to reset all host + // parameters to NULL. sqlite3_clear_bindings(stmt); // Return if domain was found in current table diff --git a/src/database/gravity-db.h b/src/database/gravity-db.h index 097680c8..a675e431 100644 --- a/src/database/gravity-db.h +++ b/src/database/gravity-db.h @@ -29,5 +29,4 @@ bool in_blacklist(const char *domain, const int clientID, clientsData* client); bool gravityDB_get_regex_client_groups(clientsData* client, const int numregex, const int *regexid, const unsigned char type, const char* table, const int clientID); - #endif //GRAVITY_H diff --git a/src/dnsmasq/dnsmasq.c b/src/dnsmasq/dnsmasq.c index 5577884d..b324b217 100644 --- a/src/dnsmasq/dnsmasq.c +++ b/src/dnsmasq/dnsmasq.c @@ -1484,8 +1484,10 @@ static void async_event(int pipe, time_t now) my_syslog(LOG_INFO, _("exiting on receipt of SIGTERM")); flush_log(); + /*** Pi-hole modification ***/ // exit(EC_GOOD); terminate = 1; + /*** Pi-hole modification ***/ } } @@ -1822,6 +1824,10 @@ static void check_dns_listeners(time_t now) #ifndef NO_FORK if (!option_bool(OPT_DEBUG)) { + /*** Pi-hole modification ***/ + // TCP workers ignore all signals except SIGALRM + FTL_TCP_worker_terminating(); + /*** Pi-hole modification ***/ flush_log(); _exit(0); } diff --git a/src/main.c b/src/main.c index 83b0b394..72b69be2 100644 --- a/src/main.c +++ b/src/main.c @@ -121,6 +121,6 @@ int main (int argc, char* argv[]) //Remove PID file removepid(); - logg("########## FTL terminated after %.1f ms! ##########", timer_elapsed_msec(EXIT_TIMER)); + logg("########## FTL terminated after %e s! ##########", 1e-3*timer_elapsed_msec(EXIT_TIMER)); return EXIT_SUCCESS; } diff --git a/src/vector.c b/src/vector.c index 4ee0235e..4c1a710c 100644 --- a/src/vector.c +++ b/src/vector.c @@ -14,7 +14,6 @@ // logg() #include "log.h" -/********************************* type sqlite3_stmt_vec *********************************/ sqlite3_stmt_vec *new_sqlite3_stmt_vec(unsigned int initial_size) { if(config.debug & DEBUG_VECTORS) @@ -36,9 +35,9 @@ static void resize_sqlite3_stmt_vec(sqlite3_stmt_vec *v, unsigned int capacity) if(config.debug & DEBUG_VECTORS) logg("Resizing sqlite3_stmt* vector %p from %u to %u", v, v->capacity, capacity); - // If ptr is NULL, the call to realloc(ptr, size) is - // equivalent to malloc(size) so we can use it also for - // initializing a vector for the first time. + // If ptr is NULL, the call to realloc(ptr, size) is equivalent to + // malloc(size) so we can use it also for initializing a vector for the + // first time. sqlite3_stmt **items = realloc(v->items, sizeof(sqlite3_stmt *) * capacity); if(!items) { @@ -73,8 +72,8 @@ void set_sqlite3_stmt_vec(sqlite3_stmt_vec *v, unsigned int index, sqlite3_stmt if(index >= v->capacity) { // Allocate more memory when trying to set a statement vector entry with - // an index larger than the current array size (this makes set an equivalent - // alternative to append) + // an index larger than the current array size (this makes set an + // equivalent alternative to append) resize_sqlite3_stmt_vec(v, index + VEC_ALLOC_STEP); } @@ -82,9 +81,9 @@ void set_sqlite3_stmt_vec(sqlite3_stmt_vec *v, unsigned int index, sqlite3_stmt v->items[index] = item; } -// This function has no effects except to return a value. It can -// be subject to data flow analysis and might be eliminated. -// Hence, we add the "pure" attribute to this function. +// This function has no effects except to return a value. It can be subject to +// data flow analysis and might be eliminated. Hence, we add the "pure" +// attribute to this function. sqlite3_stmt * __attribute__((pure)) get_sqlite3_stmt_vec(sqlite3_stmt_vec *v, unsigned int index) { if(v == NULL) @@ -114,8 +113,7 @@ void free_sqlite3_stmt_vec(sqlite3_stmt_vec *v) // Free elements of the vector... free(v->items); - // ...and then then vector itself + // ...and then the vector itself free(v); v = NULL; } -/********************************* type sqlite3_stmt_vec *********************************/ \ No newline at end of file diff --git a/src/vector.h b/src/vector.h index 2870ef84..f39aa987 100644 --- a/src/vector.h +++ b/src/vector.h @@ -1,5 +1,5 @@ /* Pi-hole: A black hole for Internet advertisements -* (c) 2019 Pi-hole, LLC (https://pi-hole.net) +* (c) 2020 Pi-hole, LLC (https://pi-hole.net) * Network-wide ad blocking via your own hardware. * * FTL Engine @@ -35,4 +35,4 @@ sqlite3_stmt* get_sqlite3_stmt_vec(sqlite3_stmt_vec *v, unsigned int index) __at void del_sqlite3_stmt_vec(sqlite3_stmt_vec *v, unsigned int index); void free_sqlite3_stmt_vec(sqlite3_stmt_vec *v); -#endif //VECTOR_H \ No newline at end of file +#endif //VECTOR_H