Skip to content

Commit

Permalink
Merge pull request #1060 from pi-hole/release/v5.7
Browse files Browse the repository at this point in the history
Pi-hole FTL v5.7
  • Loading branch information
PromoFaux committed Feb 16, 2021
2 parents da89cc6 + cdf4e27 commit 2999e2b
Show file tree
Hide file tree
Showing 18 changed files with 385 additions and 159 deletions.
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ set(sources
main.h
overTime.c
overTime.h
procps.c
procps.h
regex.c
regex_r.h
resolve.c
Expand Down
21 changes: 20 additions & 1 deletion src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,25 @@ void read_FTLconf(void)
logg(" REFRESH_HOSTNAMES: Periodically refreshing IPv4 names");
}

// RATE_LIMIT
// defaults to: 1000 queries / 60 seconds
config.rate_limit.count = 1000;
config.rate_limit.interval = 60;
buffer = parse_FTLconf(fp, "RATE_LIMIT");

unsigned int count = 0, interval = 0;
if(buffer != NULL && sscanf(buffer, "%u/%u", &count, &interval) == 2)
{
config.rate_limit.count = count;
config.rate_limit.interval = interval;
}

if(config.rate_limit.count > 0)
logg(" RATE_LIMIT: Rate-limiting client making more than %u queries in %u second%s",
config.rate_limit.count, config.rate_limit.interval, config.rate_limit.interval == 1 ? "" : "s");
else
logg(" RATE_LIMIT: Disabled");

// Read DEBUG_... setting from pihole-FTL.conf
read_debuging_settings(fp);

Expand Down Expand Up @@ -523,7 +542,7 @@ static char *parse_FTLconf(FILE *fp, const char * key)

// Go to beginning of file
fseek(fp, 0L, SEEK_SET);

if(config.debug & DEBUG_EXTRA)
logg("initial: conflinebuffer = %p, keystr = %p, size = %zu", conflinebuffer, keystr, size);

Expand Down
6 changes: 5 additions & 1 deletion src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,14 @@ typedef struct {
int dns_port;
unsigned int delay_startup;
unsigned int network_expire;
struct {
unsigned int count;
unsigned int interval;
} rate_limit;
enum debug_flags debug;
time_t DBinterval;
} ConfigStruct;
ASSERT_SIZEOF(ConfigStruct, 56, 48, 48);
ASSERT_SIZEOF(ConfigStruct, 64, 56, 56);

typedef struct {
const char* conf;
Expand Down
32 changes: 20 additions & 12 deletions src/database/query-table.c
Original file line number Diff line number Diff line change
Expand Up @@ -359,12 +359,13 @@ void DB_read_queries(void)
continue;
}

const int status = sqlite3_column_int(stmt, 3);
if(status < QUERY_UNKNOWN || status >= QUERY_STATUS_MAX)
const int status_int = sqlite3_column_int(stmt, 3);
if(status_int < QUERY_UNKNOWN || status_int >= QUERY_STATUS_MAX)
{
logg("FTL_db warn: STATUS should be within [%i,%i] but is %i", QUERY_UNKNOWN, QUERY_STATUS_MAX-1, status);
logg("FTL_db warn: STATUS should be within [%i,%i] but is %i", QUERY_UNKNOWN, QUERY_STATUS_MAX-1, status_int);
continue;
}
const enum query_status status = status_int;

const char * domainname = (const char *)sqlite3_column_text(stmt, 4);
if(domainname == NULL)
Expand All @@ -387,22 +388,21 @@ void DB_read_queries(void)
continue;
}

const char *upstream = NULL;
const char *buffer = NULL;
int upstreamID = -1; // Default if not forwarded
// Determine upstreamID only when status == 2 (forwarded) as the
// field need not to be filled for other query status types
// Try to extract the upstream from the "forward" column if non-empty
if(sqlite3_column_bytes(stmt, 6) > 0 &&
(upstream = (const char *)sqlite3_column_text(stmt, 6)) != NULL)
(buffer = (const char *)sqlite3_column_text(stmt, 6)) != NULL)
{
// Get IP address and port of upstream destination
char serv_addr[INET6_ADDRSTRLEN] = { 0 };
unsigned int serv_port = 53;
// We limit the number of bytes written into the serv_addr buffer
// to prevent buffer overflows. If there is no port available in
// the database, we skip extracting them and use the default port
sscanf(upstream, "%"xstr(INET6_ADDRSTRLEN)"[^#]#%u", serv_addr, &serv_port);
sscanf(buffer, "%"xstr(INET6_ADDRSTRLEN)"[^#]#%u", serv_addr, &serv_port);
serv_addr[INET6_ADDRSTRLEN-1] = '\0';
upstreamID = findUpstreamID(serv_addr, (in_port_t)serv_port, true);
upstreamID = findUpstreamID(serv_addr, (in_port_t)serv_port);
}

// Obtain IDs only after filtering which queries we want to keep
Expand Down Expand Up @@ -431,7 +431,7 @@ void DB_read_queries(void)
query->type = TYPE_OTHER;
query->qtype = type - 100;
}

query->status = status;
query->domainID = domainID;
query->clientID = clientID;
Expand Down Expand Up @@ -522,7 +522,15 @@ void DB_read_queries(void)
break;

case QUERY_FORWARDED: // Forwarded
case QUERY_RETRIED: // (fall through)
case QUERY_RETRIED_DNSSEC: // (fall through)
counters->forwarded++;
upstreamsData *upstream = getUpstream(upstreamID, true);
if(upstream != NULL)
{
upstream->count++;
upstream->lastQuery = queryTimeStamp;
}
// Update overTime data structure
overTime[timeidx].forwarded++;
break;
Expand All @@ -533,11 +541,11 @@ void DB_read_queries(void)
overTime[timeidx].cached++;
break;

case QUERY_RETRIED: // Retried query
case QUERY_RETRIED_DNSSEC: // fall through
case QUERY_IN_PROGRESS:
// Nothing to be done here
break;

case QUERY_STATUS_MAX:
default:
logg("Warning: Found unknown status %i in long term database!", status);
break;
Expand Down
14 changes: 2 additions & 12 deletions src/datastructure.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ int findQueryID(const int id)
return -1;
}

int findUpstreamID(const char * upstreamString, const in_port_t port, const bool count)
int findUpstreamID(const char * upstreamString, const in_port_t port)
{
// Go through already knows upstream servers and see if we used one of those
for(int upstreamID=0; upstreamID < counters->upstreams; upstreamID++)
Expand All @@ -82,14 +82,7 @@ int findUpstreamID(const char * upstreamString, const in_port_t port, const bool
continue;

if(strcmp(getstr(upstream->ippos), upstreamString) == 0 && upstream->port == port)
{
if(count)
{
upstream->count++;
upstream->lastQuery = time(NULL);
}
return upstreamID;
}
}
// This upstream server is not known
// Store ID
Expand All @@ -110,10 +103,7 @@ int findUpstreamID(const char * upstreamString, const in_port_t port, const bool
// Set magic byte
upstream->magic = MAGICBYTE;
// Initialize its counter
if(count)
upstream->count = 1;
else
upstream->count = 0;
upstream->count = 0;
// Save upstream destination IP address
upstream->ippos = addstr(upstreamString);
upstream->failed = 0;
Expand Down
5 changes: 3 additions & 2 deletions src/datastructure.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ typedef struct {
int blockedcount;
int aliasclient_id;
unsigned int id;
unsigned int rate_limit;
unsigned int numQueriesARP;
int overTime[OVERTIME_SLOTS];
size_t groupspos;
Expand All @@ -88,7 +89,7 @@ typedef struct {
time_t lastQuery;
time_t firstSeen;
} clientsData;
ASSERT_SIZEOF(clientsData, 688, 664, 664);
ASSERT_SIZEOF(clientsData, 696, 668, 668);

typedef struct {
unsigned char magic;
Expand All @@ -111,7 +112,7 @@ ASSERT_SIZEOF(DNSCacheData, 16, 16, 16);

void strtolower(char *str);
int findQueryID(const int id);
int findUpstreamID(const char * upstream, const in_port_t port, const bool count);
int findUpstreamID(const char * upstream, const in_port_t port);
int findDomainID(const char *domain, const bool count);
int findClientID(const char *client, const bool count, const bool aliasclient);
int findCacheID(int domainID, int clientID, enum query_types query_type);
Expand Down
46 changes: 18 additions & 28 deletions src/dhcp-discover.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ static int get_hardware_address(const int sock, const char *interface_name, unsi
logg_sameline("Hardware address of this interface: ");
for (uint8_t i = 0; i < 6; ++i)
logg_sameline("%02x%s", mac[i], i < 5 ? ":" : "");
logg("");
logg(" ");
#endif
return true;
}
Expand Down Expand Up @@ -201,14 +201,8 @@ static bool send_dhcp_discover(const int sock, const uint32_t xid, const char *i
discover_packet.options[5] = '\x01'; // DHCP message option length in bytes
discover_packet.options[6] = 1; // DHCP message type code for DHCPDISCOVER

// Request a lease with validity of 1 second
discover_packet.options[7] = 51; // Lease time type option identifier
discover_packet.options[8] = '\x04'; // DHCP message option length in bytes
const uint32_t lease_time = htonl(1);
memcpy(&discover_packet.options[9], &lease_time, sizeof(lease_time));

// Place end option at the end of the options
discover_packet.options[13] = 255;
discover_packet.options[7] = 255;

// send the DHCPDISCOVER packet to the specified address
struct sockaddr_in target;
Expand Down Expand Up @@ -452,12 +446,12 @@ static bool get_dhcp_offer(const int sock, const uint32_t xid, const char *iface

if(!receive_dhcp_packet(&offer_packet, sizeof(offer_packet), iface, sock, start_time, &source))
continue;
#if DEBUG
#ifdef DEBUG
else
responses++;
#endif

#if DEBUG
#ifdef DEBUG
logg(" DHCPOFFER XID: %lu (0x%X)", (unsigned long) ntohl(offer_packet.xid), ntohl(offer_packet.xid));
#endif

Expand Down Expand Up @@ -555,19 +549,20 @@ static void *dhcp_discover_iface(void *args)
srand(time(NULL));
const uint32_t xid = random();

#ifdef PROBE_LOCAL
// Probe a local server listining on this interface
// send DHCPDISCOVER packet to interface address
struct sockaddr_in ifaddr = { 0 };
memcpy(&ifaddr, ((struct ifaddrs*)args)->ifa_addr, sizeof(ifaddr));
send_dhcp_discover(dhcp_socket, xid, iface, ifaddr.sin_addr.s_addr);
#endif

#ifdef PROBE_BCAST
// Probe distant servers
// send DHCPDISCOVER packet to broadcast address
send_dhcp_discover(dhcp_socket, xid, iface, mac, INADDR_BROADCAST);
#endif
if(strcmp(iface, "lo") == 0)
{
// Probe a local server listening on this interface
// Send DHCPDISCOVER packet to interface address
struct sockaddr_in ifaddr = { 0 };
memcpy(&ifaddr, ((struct ifaddrs*)args)->ifa_addr, sizeof(ifaddr));
send_dhcp_discover(dhcp_socket, xid, iface, mac, ifaddr.sin_addr.s_addr);
}
else
{
// Probe distant servers
// Send DHCPDISCOVER packet to broadcast address
send_dhcp_discover(dhcp_socket, xid, iface, mac, INADDR_BROADCAST);
}

// wait for a DHCPOFFER packet
get_dhcp_offer(dhcp_socket, xid, iface, mac);
Expand Down Expand Up @@ -615,13 +610,8 @@ int run_dhcp_discover(void)
int tid = 0;
while(tmp != NULL && tid < MAXTHREADS)
{
#ifdef PROBE_LOCAL
// Create a thread for interfaces of type AF_INET (IPv4 sockets)
if(tmp->ifa_addr && tmp->ifa_addr->sa_family == AF_INET)
#else
// Create a thread for interfaces of type AF_PACKET
if(tmp->ifa_addr && tmp->ifa_addr->sa_family == AF_PACKET)
#endif
{
if(pthread_create(&scanthread[tid], &attr, dhcp_discover_iface, tmp ) != 0)
{
Expand Down
8 changes: 8 additions & 0 deletions src/dnsmasq/forward.c
Original file line number Diff line number Diff line change
Expand Up @@ -1709,6 +1709,10 @@ void receive_query(struct listener *listen, time_t now)
FTL_get_blocking_metadata(&addrp, &flags);
log_query(flags, daemon->namebuff, addrp, (char*)blockingreason);
n = setup_reply(header, n, addrp, flags, daemon->local_ttl);
// The pseudoheader may contain important information such as EDNS0 version important for
// some DNS resolvers (such as systemd-resolved) to work properly. We should not discard them.
if (have_pseudoheader)
n = add_pseudoheader(header, n, ((unsigned char *) header) + PACKETSZ, daemon->edns_pktsz, 0, NULL, 0, do_bit, 0);
send_from(listen->fd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND), (char *)header, n, (union mysockaddr*)&source_addr, &dst_addr, if_index);
return;
}
Expand Down Expand Up @@ -2100,6 +2104,10 @@ unsigned char *tcp_request(int confd, time_t now,
FTL_get_blocking_metadata(&addrp, &flags);
log_query(flags, daemon->namebuff, addrp, (char*)blockingreason);
m = setup_reply(header, size, addrp, flags, daemon->local_ttl);
// The pseudoheader may contain important information such as EDNS0 version important for
// some DNS resolvers (such as systemd-resolved) to work properly. We should not discard them.
if (have_pseudoheader)
m = add_pseudoheader(header, m, ((unsigned char *) header) + 65536, daemon->edns_pktsz, 0, NULL, 0, do_bit, 0);
}
else
{
Expand Down
4 changes: 2 additions & 2 deletions src/dnsmasq/option.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#include <setjmp.h>

/* Pi-hole modification */
extern char *get_FTL_version(void);
#include "../log.h"
/************************/

static volatile int mem_recover = 0;
Expand Down Expand Up @@ -5059,7 +5059,7 @@ void read_opts(int argc, char **argv, char *compile_opts)
/************************/
#endif
/******** Pi-hole modification ********/
add_txt("version.FTL", get_FTL_version(), 0 );
add_txt("version.FTL", (char*)get_FTL_version(), 0 );
/**************************************/

while (1)
Expand Down
Loading

0 comments on commit 2999e2b

Please sign in to comment.