Free allocated memory after ordinary termination of TCP workers (TCP connection closed)

Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
DL6ER
2020-04-06 15:11:32 +02:00
parent 7d3e960324
commit 536ef08ce5
6 changed files with 50 additions and 51 deletions
+32 -36
View File
@@ -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
-1
View File
@@ -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
+6
View File
@@ -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);
}
+1 -1
View File
@@ -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;
}
+9 -11
View File
@@ -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 *********************************/
+2 -2
View File
@@ -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
#endif //VECTOR_H