Skip to content

Commit

Permalink
Merge pull request #853 from pi-hole/release/v5.2
Browse files Browse the repository at this point in the history
Pi-hole FTL v5.2
  • Loading branch information
PromoFaux authored Aug 9, 2020
2 parents b522646 + 3414def commit dbd4a69
Show file tree
Hide file tree
Showing 28 changed files with 509 additions and 178 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ pihole-FTL
# Versioning files (generated by Makefile)
version*

# CMake files
# CMake files generated during compilation
/cmake/
/cmake-build-debug/
/cmake-build-release/

Expand Down
12 changes: 7 additions & 5 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,14 @@ add_custom_target(
COMMAND ${CMAKE_COMMAND} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -P ${CMAKE_CURRENT_SOURCE_DIR}/gen_version.cmake
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})

add_library(FTL OBJECT ${sources})
target_compile_options(FTL PRIVATE ${EXTRAWARN})
target_include_directories(FTL PRIVATE ${PROJECT_SOURCE_DIR}/src)
add_dependencies(FTL gen_version)


add_executable(pihole-FTL
${sources}
$<TARGET_OBJECTS:FTL>
$<TARGET_OBJECTS:api>
$<TARGET_OBJECTS:database>
$<TARGET_OBJECTS:dnsmasq>
Expand All @@ -164,10 +170,6 @@ if(STATIC STREQUAL "true")
set_target_properties(pihole-FTL PROPERTIES LINK_SEARCH_END_STATIC ON)
target_link_libraries(pihole-FTL -static-libgcc -static -static-pie)
endif()
target_compile_options(pihole-FTL PRIVATE ${EXTRAWARN})
target_include_directories(pihole-FTL PRIVATE ${PROJECT_SOURCE_DIR}/src)
add_dependencies(pihole-FTL gen_version)

set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads REQUIRED)
Expand Down
23 changes: 23 additions & 0 deletions src/api/socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,29 @@ bool dualstack = false;
bool ipv4telnet = false, ipv6telnet = false, sock_avail = false;
bool istelnet[MAXCONNS];

void saveport(int port)
{
FILE *f;
// Open "w" for truncation/creating file
if((f = fopen(FTLfiles.port, "w")) == NULL)
{
// Opening failed (permissions, path does not exist, etc.)
logg("WARNING: Unable to write used port to file");
logg(" (API might not find the port)");
}
else if(port > 0)
{
// Save port to file
fprintf(f, "%i", port);
fclose(f);
}
else
{
// FTL is terminating: Leave file truncated
fclose(f);
}
}

static bool bind_to_telnet_port_IPv4(int *socketdescriptor)
{
// IPv4 socket
Expand Down
1 change: 1 addition & 0 deletions src/api/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#ifndef SOCKET_H
#define SOCKET_H

void saveport(int port);
void close_telnet_socket(void);
void close_unix_socket(bool unlink_file);
void seom(const int sock);
Expand Down
7 changes: 7 additions & 0 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include "log.h"
// nice()
#include <unistd.h>
// saveport()
#include "api/socket.h"

ConfigStruct config;
FTLFileNamesStruct FTLfiles = {
Expand All @@ -29,6 +31,7 @@ FTLFileNamesStruct FTLfiles = {
NULL,
NULL,
NULL,
NULL,
NULL
};

Expand Down Expand Up @@ -300,6 +303,10 @@ void read_FTLconf(void)
// PIDFILE
getpath(fp, "PIDFILE", "/run/pihole-FTL.pid", &FTLfiles.pid);

// PORTFILE
getpath(fp, "PORTFILE", "/run/pihole-FTL.port", &FTLfiles.port);
saveport(config.port);

// SOCKETFILE
getpath(fp, "SOCKETFILE", "/run/pihole/FTL.sock", &FTLfiles.socketfile);

Expand Down
1 change: 1 addition & 0 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ typedef struct {
const char* snapConf;
char* log;
char* pid;
char* port;
char* socketfile;
char* FTL_db;
char* gravity_db;
Expand Down
18 changes: 18 additions & 0 deletions src/database/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,24 @@ void db_init(void)
dbversion = db_get_FTL_property(DB_VERSION);
}

// Update to version 7 if lower
if(dbversion < 7)
{
// 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))
{
logg("Column additional_info not initialized, database not available");
dbclose();

database = false;
return;
}
// Get updated version
dbversion = db_get_FTL_property(DB_VERSION);
}

// Close database to prevent having it opened all time
// We already closed the database when we returned earlier
dbclose();
Expand Down
8 changes: 8 additions & 0 deletions src/database/gravity-db.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ void gravityDB_forked(void)
gravityDB_open();
}

void gravityDB_reopen(void)
{
lock_shm();
gravityDB_close();
gravityDB_open();
unlock_shm();
}

// Open gravity database
bool gravityDB_open(void)
{
Expand Down
1 change: 1 addition & 0 deletions src/database/gravity-db.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
enum gravity_tables { GRAVITY_TABLE, EXACT_BLACKLIST_TABLE, EXACT_WHITELIST_TABLE, REGEX_BLACKLIST_TABLE, REGEX_WHITELIST_TABLE, UNKNOWN_TABLE } __attribute__ ((packed));

void gravityDB_forked(void);
void gravityDB_reopen(void);
bool gravityDB_open(void);
bool gravityDB_prepare_client_statements(const int clientID, clientsData* client);
void gravityDB_close(void);
Expand Down
83 changes: 68 additions & 15 deletions src/database/query-table.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ void DB_save_queries(void)
return;
}

rc = sqlite3_prepare_v2(FTL_db, "INSERT INTO queries VALUES (NULL,?,?,?,?,?,?)", -1, &stmt, NULL);
rc = sqlite3_prepare_v2(FTL_db, "INSERT INTO queries VALUES (NULL,?,?,?,?,?,?,?)", -1, &stmt, NULL);
if( rc != SQLITE_OK )
{
const char *text, *spaces;
Expand Down Expand Up @@ -165,6 +165,31 @@ void DB_save_queries(void)
sqlite3_bind_null(stmt, 6);
}

// ADDITIONAL_INFO
if(query->status == QUERY_GRAVITY_CNAME ||
query->status == QUERY_REGEX_CNAME ||
query->status == QUERY_BLACKLIST_CNAME)
{
// Restore domain blocked during deep CNAME inspection if applicable
const char* cname = getCNAMEDomainString(query);
sqlite3_bind_text(stmt, 7, cname, -1, SQLITE_STATIC);
}
else if(query->status == QUERY_REGEX)
{
// Restore regex ID if applicable
const int cacheID = findCacheID(query->domainID, query->clientID);
DNSCacheData *cache = getDNSCache(cacheID, true);
if(cache != NULL)
sqlite3_bind_int(stmt, 7, cache->black_regex_idx);
else
sqlite3_bind_null(stmt, 7);
}
else
{
// Nothing to add here
sqlite3_bind_null(stmt, 7);
}

// Step and check if successful
rc = sqlite3_step(stmt);
sqlite3_clear_bindings(stmt);
Expand Down Expand Up @@ -303,27 +328,28 @@ void DB_read_queries(void)
// Get time stamp 24 hours in the past
const time_t now = time(NULL);
const time_t mintime = now - config.maxlogage;
char *querystr = NULL;
int rc = asprintf(&querystr, "SELECT * FROM queries WHERE timestamp >= %li", mintime);
if(rc < 42)
{
logg("DB_read_queries() - Memory allocation error: %s", sqlite3_errstr(rc));
dbclose();
return;
}
const char *querystr = "SELECT * FROM queries WHERE timestamp >= ?";
// Log FTL_db query string in debug mode
if(config.debug & DEBUG_DATABASE)
logg("DB_read_queries(): \"%s\"", querystr);
logg("DB_read_queries(): \"%s\" with ? = %li", querystr, mintime);

// Prepare SQLite3 statement
sqlite3_stmt* stmt = NULL;
rc = sqlite3_prepare_v2(FTL_db, querystr, -1, &stmt, NULL);
int rc = sqlite3_prepare_v2(FTL_db, querystr, -1, &stmt, NULL);
if( rc != SQLITE_OK ){
logg("DB_read_queries() - SQL error prepare: %s", sqlite3_errstr(rc));
dbclose();
return;
}

// Bind limit
if((rc = sqlite3_bind_int(stmt, 1, mintime)) != SQLITE_OK)
{
logg("DB_read_queries() - Failed to bind type mintime: %s", sqlite3_errstr(rc));
dbclose();
return;
}

// Loop through returned database rows
while((rc = sqlite3_step(stmt)) == SQLITE_ROW)
{
Expand Down Expand Up @@ -444,6 +470,34 @@ void DB_read_queries(void)
// Increase DNS queries counter
counters->queries++;

// Get additional information from the additional_info column if applicable
if(status == QUERY_GRAVITY_CNAME ||
status == QUERY_REGEX_CNAME ||
status == QUERY_BLACKLIST_CNAME)
{
// QUERY_*_CNAME: Getdomain causing the blocking
const char *CNAMEdomain = (const char *)sqlite3_column_text(stmt, 7);
if(CNAMEdomain != NULL && strlen(CNAMEdomain) > 0)
{
// Add domain to FTL's memory but do not count it. Seeing a
// domain in the middle of a CNAME trajectory does not mean
// it was queried intentionally.
const int CNAMEdomainID = findDomainID(CNAMEdomain, false);
query->CNAME_domainID = CNAMEdomainID;
}
}
else if(status == QUERY_REGEX)
{
// QUERY_REGEX: Set ID regex which was the reson for blocking
const int cacheID = findCacheID(query->domainID, query->clientID);
DNSCacheData *cache = getDNSCache(cacheID, true);
// Only load if
// a) we have a chace entry
// b) the value of additional_info is not NULL (0 bytes storage size)
if(cache != NULL && sqlite3_column_bytes(stmt, 7) != 0)
cache->black_regex_idx = sqlite3_column_int(stmt, 7);
}

// Increment status counters
switch(status)
{
Expand All @@ -457,9 +511,9 @@ void DB_read_queries(void)
case QUERY_EXTERNAL_BLOCKED_IP: // Blocked by external provider
case QUERY_EXTERNAL_BLOCKED_NULL: // Blocked by external provider
case QUERY_EXTERNAL_BLOCKED_NXRA: // Blocked by external provider
case QUERY_GRAVITY_CNAME: // Blocked by gravity
case QUERY_REGEX_CNAME: // Blocked by regex blacklist
case QUERY_BLACKLIST_CNAME: // Blocked by exact blacklist
case QUERY_GRAVITY_CNAME: // Blocked by gravity (inside CNAME path)
case QUERY_REGEX_CNAME: // Blocked by regex blacklist (inside CNAME path)
case QUERY_BLACKLIST_CNAME: // Blocked by exact blacklist (inside CNAME path)
counters->blocked++;
// Get domain pointer
domainsData* domain = getDomain(domainID, true);
Expand Down Expand Up @@ -503,5 +557,4 @@ void DB_read_queries(void)
// Finalize SQLite3 statement
sqlite3_finalize(stmt);
dbclose();
free(querystr);
}
22 changes: 7 additions & 15 deletions src/datastructure.c
Original file line number Diff line number Diff line change
Expand Up @@ -355,20 +355,13 @@ const char *getClientNameString(const queriesData* query)

void FTL_reset_per_client_domain_data(void)
{
for(int domainID = 0; domainID < counters->domains; domainID++)
for(int cacheID = 0; cacheID < counters->dns_cache_size; cacheID++)
{
domainsData *domain = getDomain(domainID, true);
if(domain == NULL)
continue;

for(int cacheID = 0; cacheID < counters->dns_cache_size; cacheID++)
{
// Reset all blocking yes/no fields for all domains and clients
// This forces a reprocessing of all available filters for any
// given domain and client the next time they are seen
DNSCacheData *dns_cache = getDNSCache(cacheID, true);
dns_cache->blocking_status = UNKNOWN_BLOCKED;
}
// Reset all blocking yes/no fields for all domains and clients
// This forces a reprocessing of all available filters for any
// given domain and client the next time they are seen
DNSCacheData *dns_cache = getDNSCache(cacheID, true);
dns_cache->blocking_status = UNKNOWN_BLOCKED;
}
}

Expand All @@ -378,8 +371,7 @@ void FTL_reload_all_domainlists(void)
flush_message_table();

// (Re-)open gravity database connection
gravityDB_close();
gravityDB_open();
gravityDB_reopen();

// Reset number of blocked domains
counters->gravity = gravityDB_count(GRAVITY_TABLE);
Expand Down
Loading

0 comments on commit dbd4a69

Please sign in to comment.