mirror of
https://github.com/pi-hole/FTL.git
synced 2024-10-26 16:52:18 +02:00
Merge pull request #1111 from pi-hole/new/reply_pihole_hostname
Handle pi.hole and hostname interface-dependent
This commit is contained in:
@@ -22,6 +22,8 @@
|
||||
#include "database/common.h"
|
||||
// destroy_shmem()
|
||||
#include "shmem.h"
|
||||
// uname()
|
||||
#include <sys/utsname.h>
|
||||
// killed
|
||||
#include "signals.h"
|
||||
|
||||
@@ -141,6 +143,30 @@ char *getUserName(void)
|
||||
return name;
|
||||
}
|
||||
|
||||
// "man 7 hostname" says:
|
||||
//
|
||||
// Each element of the hostname must be from 1 to 63 characters long and the
|
||||
// entire hostname, including the dots, can be at most 253 characters long.
|
||||
//
|
||||
// Valid characters for hostnames are ASCII(7) letters from a to z, the
|
||||
// digits from 0 to 9, and the hyphen (-). A hostname may not start with a
|
||||
// hyphen.
|
||||
#define HOSTNAMESIZE 256
|
||||
static char nodename[HOSTNAMESIZE] = { 0 };
|
||||
const char *hostname(void)
|
||||
{
|
||||
// Ask kernel for node name if not known
|
||||
// This is equivalent to "uname -n"
|
||||
if(nodename[0] == '\0')
|
||||
{
|
||||
struct utsname buf;
|
||||
if(uname(&buf) == 0)
|
||||
strncpy(nodename, buf.nodename, HOSTNAMESIZE);
|
||||
nodename[HOSTNAMESIZE-1] = '\0';
|
||||
}
|
||||
return nodename;
|
||||
}
|
||||
|
||||
void delay_startup(void)
|
||||
{
|
||||
// Exit early if not sleeping
|
||||
|
||||
@@ -16,6 +16,7 @@ extern pthread_t threads[THREADS_MAX];
|
||||
void go_daemon(void);
|
||||
void savepid(void);
|
||||
char *getUserName(void);
|
||||
const char *hostname(void);
|
||||
void delay_startup(void);
|
||||
bool is_fork(const pid_t mpid, const pid_t pid) __attribute__ ((const));
|
||||
void cleanup(const int ret);
|
||||
|
||||
+1
-1
@@ -102,7 +102,7 @@ ASSERT_SIZEOF(domainsData, 24, 16, 16);
|
||||
typedef struct {
|
||||
unsigned char magic;
|
||||
enum domain_client_status blocking_status;
|
||||
unsigned char force_reply;
|
||||
enum reply_type force_reply;
|
||||
enum query_types query_type;
|
||||
int domainID;
|
||||
int clientID;
|
||||
|
||||
+80
-28
@@ -58,7 +58,7 @@ static void query_blocked(queriesData* query,
|
||||
|
||||
// Static blocking metadata
|
||||
static union all_addr null_addrp = {{ 0 }};
|
||||
static unsigned char force_next_DNS_reply = 0u;
|
||||
static enum reply_type force_next_DNS_reply = REPLY_UNKNOWN;
|
||||
|
||||
// Adds debug information to the regular pihole.log file
|
||||
char debug_dnsmasq_lines = 0;
|
||||
@@ -82,10 +82,28 @@ void FTL_iface(const int ifidx, const struct irec *ifaces)
|
||||
|
||||
// Copy overwrite addresses if configured via REPLY_ADDR4 and/or REPLY_ADDR6 settings
|
||||
if(config.reply_addr.overwrite_v4)
|
||||
{
|
||||
memcpy(&next_iface.addr4, &config.reply_addr.v4, sizeof(config.reply_addr.v4));
|
||||
|
||||
if(config.debug & DEBUG_NETWORKING)
|
||||
{
|
||||
char buffer[ADDRSTRLEN+1] = { 0 };
|
||||
inet_ntop(AF_INET, &next_iface.addr4, buffer, ADDRSTRLEN);
|
||||
logg("Interface (%d) %s OVERWRITES IPv4 address %s", ifidx, next_iface.name, buffer);
|
||||
}
|
||||
}
|
||||
if(config.reply_addr.overwrite_v6)
|
||||
{
|
||||
memcpy(&next_iface.addr6, &config.reply_addr.v6, sizeof(config.reply_addr.v6));
|
||||
|
||||
if(config.debug & DEBUG_NETWORKING)
|
||||
{
|
||||
char buffer[ADDRSTRLEN+1] = { 0 };
|
||||
inet_ntop(AF_INET6, &next_iface.addr6, buffer, ADDRSTRLEN);
|
||||
logg("Interface (%d) %s OVERWRITES IPv6 address %s", ifidx, next_iface.name, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
// Use dummy when interface record is not available
|
||||
next_iface.name[0] = '-';
|
||||
next_iface.name[1] = '\0';
|
||||
@@ -396,8 +414,8 @@ static bool _FTL_check_blocking(int queryID, int domainID, int clientID, const c
|
||||
// Truncate "_esni." from queried domain if the parenting domain was the reason for blocking this query
|
||||
blockedDomain = domainstr + 6u;
|
||||
// Force next DNS reply to be NXDOMAIN for _esni.* queries
|
||||
force_next_DNS_reply = NXDOMAIN;
|
||||
dns_cache->force_reply = NXDOMAIN;
|
||||
force_next_DNS_reply = REPLY_NXDOMAIN;
|
||||
dns_cache->force_reply = REPLY_NXDOMAIN;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -633,9 +651,24 @@ bool _FTL_new_query(const unsigned int flags, const char *name,
|
||||
return false;
|
||||
}
|
||||
|
||||
// If domain is "pi.hole" we skip this query
|
||||
if(strcasecmp(name, "pi.hole") == 0)
|
||||
return false;
|
||||
// If domain is "pi.hole" or the local hostname we skip analyzing this query
|
||||
// and, instead, immediately reply with the IP address
|
||||
if(strcasecmp(name, "pi.hole") == 0 || strcasecmp(name, hostname()) == 0)
|
||||
{
|
||||
if(querytype == TYPE_A || querytype == TYPE_AAAA || querytype == TYPE_ANY)
|
||||
{
|
||||
// "Block" this query by sending the interface IP address
|
||||
force_next_DNS_reply = REPLY_IP;
|
||||
if(config.debug & DEBUG_QUERIES)
|
||||
logg("Replying to %s with interface-local IP address", name);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Don't block this query
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert domain to lower case
|
||||
char *domainString = strdup(name);
|
||||
@@ -660,7 +693,7 @@ bool _FTL_new_query(const unsigned int flags, const char *name,
|
||||
inet_ntop(family,
|
||||
family == AF_INET ?
|
||||
(union mysockaddr*)&addr->in.sin_addr :
|
||||
(union mysockaddr*)&addr->in6.sin6_addr,
|
||||
(union mysockaddr*)&addr->in6.sin6_addr,
|
||||
clientIP, ADDRSTRLEN);
|
||||
}
|
||||
|
||||
@@ -703,7 +736,7 @@ bool _FTL_new_query(const unsigned int flags, const char *name,
|
||||
}
|
||||
|
||||
// Block this query
|
||||
force_next_DNS_reply = REFUSED;
|
||||
force_next_DNS_reply = REPLY_REFUSED;
|
||||
|
||||
// Do not further process this query, Pi-hole has never seen it
|
||||
unlock_shm();
|
||||
@@ -868,19 +901,21 @@ void _FTL_get_blocking_metadata(union all_addr **addrp, unsigned int *flags, con
|
||||
// Check first if we need to force our reply to something different than the
|
||||
// default/configured blocking mode. For instance, we need to force NXDOMAIN
|
||||
// for intercepted _esni.* queries.
|
||||
if(force_next_DNS_reply == NXDOMAIN)
|
||||
if(force_next_DNS_reply == REPLY_NXDOMAIN)
|
||||
{
|
||||
*flags = F_NXDOMAIN;
|
||||
|
||||
// Reset DNS reply forcing
|
||||
force_next_DNS_reply = 0u;
|
||||
force_next_DNS_reply = REPLY_UNKNOWN;
|
||||
return;
|
||||
}
|
||||
else if(force_next_DNS_reply == REFUSED)
|
||||
else if(force_next_DNS_reply == REPLY_REFUSED)
|
||||
{
|
||||
// Empty flags result in REFUSED
|
||||
*flags = 0;
|
||||
|
||||
// Reset DNS reply forcing
|
||||
force_next_DNS_reply = 0u;
|
||||
force_next_DNS_reply = REPLY_UNKNOWN;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -894,18 +929,35 @@ void _FTL_get_blocking_metadata(union all_addr **addrp, unsigned int *flags, con
|
||||
if(*flags & F_IPV6)
|
||||
{
|
||||
// Pass blocking IPv6 address
|
||||
if(config.blockingmode == MODE_IP)
|
||||
if(config.blockingmode == MODE_IP ||
|
||||
force_next_DNS_reply == REPLY_IP)
|
||||
{
|
||||
*addrp = &next_iface.addr6;
|
||||
}
|
||||
else
|
||||
{
|
||||
*addrp = &null_addrp;
|
||||
}
|
||||
|
||||
// Reset reply forcing
|
||||
force_next_DNS_reply = REPLY_UNKNOWN;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Pass blocking IPv4 address
|
||||
if(config.blockingmode == MODE_IP || config.blockingmode == MODE_IP_NODATA_AAAA)
|
||||
if(config.blockingmode == MODE_IP ||
|
||||
config.blockingmode == MODE_IP_NODATA_AAAA ||
|
||||
force_next_DNS_reply == REPLY_IP)
|
||||
{
|
||||
*addrp = &next_iface.addr4;
|
||||
}
|
||||
else
|
||||
{
|
||||
*addrp = &null_addrp;
|
||||
}
|
||||
|
||||
// Reset reply forcing
|
||||
force_next_DNS_reply = REPLY_UNKNOWN;
|
||||
}
|
||||
|
||||
if(config.blockingmode == MODE_NX)
|
||||
@@ -1086,6 +1138,16 @@ void _FTL_reply(const unsigned int flags, const char *name, const union all_addr
|
||||
// Lock shared memory
|
||||
lock_shm();
|
||||
|
||||
// Save status in corresponding query identified by dnsmasq's ID
|
||||
const int queryID = findQueryID(id);
|
||||
if(queryID < 0)
|
||||
{
|
||||
// This may happen e.g. if the original query was "pi.hole"
|
||||
if(config.debug & DEBUG_QUERIES) logg("FTL_reply(): Query %i has not been found", id);
|
||||
unlock_shm();
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine returned result if available
|
||||
char dest[ADDRSTRLEN]; dest[0] = '\0';
|
||||
if(addr)
|
||||
@@ -1128,18 +1190,8 @@ void _FTL_reply(const unsigned int flags, const char *name, const union all_addr
|
||||
struct timeval response;
|
||||
gettimeofday(&response, 0);
|
||||
|
||||
// Save status in corresponding query identified by dnsmasq's ID
|
||||
const int i = findQueryID(id);
|
||||
if(i < 0)
|
||||
{
|
||||
// This may happen e.g. if the original query was "pi.hole"
|
||||
if(config.debug & DEBUG_QUERIES) logg("FTL_reply(): Query %i has not been found", id);
|
||||
unlock_shm();
|
||||
return;
|
||||
}
|
||||
|
||||
// Get query pointer
|
||||
queriesData* query = getQuery(i, true);
|
||||
queriesData* query = getQuery(queryID, true);
|
||||
|
||||
// Check if reply time is still unknown
|
||||
// We only process the first reply in here
|
||||
@@ -1708,7 +1760,7 @@ static void query_set_reply(const unsigned int flags, const union all_addr *addr
|
||||
queriesData* query, const struct timeval response)
|
||||
{
|
||||
// Iterate through possible values
|
||||
if(flags & F_NEG || force_next_DNS_reply == NXDOMAIN)
|
||||
if(flags & F_NEG || force_next_DNS_reply == REPLY_NXDOMAIN)
|
||||
{
|
||||
if(flags & F_NXDOMAIN)
|
||||
// NXDOMAIN
|
||||
@@ -1726,10 +1778,10 @@ static void query_set_reply(const unsigned int flags, const union all_addr *addr
|
||||
else if(flags & F_RRNAME)
|
||||
// TXT query
|
||||
query->reply = REPLY_RRNAME;
|
||||
else if((flags & F_RCODE && addr != NULL) || force_next_DNS_reply == REFUSED)
|
||||
else if((flags & F_RCODE && addr != NULL) || force_next_DNS_reply == REPLY_REFUSED)
|
||||
{
|
||||
if((addr != NULL && addr->log.rcode == REFUSED)
|
||||
|| force_next_DNS_reply == REFUSED )
|
||||
|| force_next_DNS_reply == REPLY_REFUSED )
|
||||
{
|
||||
// REFUSED query
|
||||
query->reply = REPLY_REFUSED;
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ int main (int argc, char* argv[])
|
||||
// Try to open FTL log
|
||||
init_FTL_log();
|
||||
timer_start(EXIT_TIMER);
|
||||
logg("########## FTL started! ##########");
|
||||
logg("########## FTL started on %s! ##########", hostname());
|
||||
log_FTL_version(false);
|
||||
|
||||
// Catch signals not handled by dnsmasq
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@
|
||||
|
||||
int main_dnsmasq(int argc, const char ** argv);
|
||||
|
||||
extern char * username;
|
||||
extern char *username;
|
||||
extern bool startup;
|
||||
|
||||
#endif //MAIN_H
|
||||
|
||||
Reference in New Issue
Block a user