mirror of
https://github.com/pi-hole/FTL.git
synced 2024-10-26 16:52:18 +02:00
Free allocated memory after ordinary termination of TCP workers (TCP connection closed)
Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
+32
-36
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user