Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regex extension: Specify reply type #1159

Merged
merged 4 commits into from Sep 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/database/gravity-db.c
Expand Up @@ -1223,7 +1223,7 @@ static void gravityDB_client_check_again(clientsData* client)
}
}

enum db_result in_whitelist(const char *domain, const DNSCacheData *dns_cache, clientsData* client)
enum db_result in_whitelist(const char *domain, DNSCacheData *dns_cache, clientsData* client)
{
// If list statement is not ready and cannot be initialized (e.g. no
// access to the database), we return false to prevent an FTL crash
Expand Down
2 changes: 1 addition & 1 deletion src/database/gravity-db.h
Expand Up @@ -32,7 +32,7 @@ int gravityDB_count(const enum gravity_tables list);

enum db_result in_gravity(const char *domain, clientsData *client);
enum db_result in_blacklist(const char *domain, clientsData *client);
enum db_result in_whitelist(const char *domain, const DNSCacheData *dns_cache, clientsData *client);
enum db_result in_whitelist(const char *domain, DNSCacheData *dns_cache, clientsData *client);
bool in_auditlist(const char *domain);

bool gravityDB_get_regex_client_groups(clientsData* client, const unsigned int numregex, const regexData *regex,
Expand Down
2 changes: 2 additions & 0 deletions src/datastructure.h
Expand Up @@ -133,6 +133,8 @@ const char *getClientNameString(const queriesData* query);

void change_clientcount(clientsData *client, int total, int blocked, int overTimeIdx, int overTimeMod);

const char *get_query_reply_str(const enum reply_type query) __attribute__ ((const));

// Pointer getter functions
#define getQuery(queryID, checkMagic) _getQuery(queryID, checkMagic, __LINE__, __FUNCTION__, __FILE__)
queriesData* _getQuery(int queryID, bool checkMagic, int line, const char * function, const char * file);
Expand Down
73 changes: 58 additions & 15 deletions src/dnsmasq_interface.c
Expand Up @@ -50,6 +50,7 @@
#include "database/message-table.h"

// Private prototypes
static const char *reply_status_str[QUERY_REPLY_MAX+1];
static void print_flags(const unsigned int flags);
#define query_set_reply(flags, addr, query, response) _query_set_reply(flags, addr, query, response, __FILE__, __LINE__)
static void _query_set_reply(const unsigned int flags, const union all_addr *addr, queriesData* query, const struct timeval response,
Expand All @@ -74,9 +75,10 @@ static void _query_set_dnssec(queriesData *query, const enum dnssec_status dnsse
static const char *blockingreason = NULL;
static union all_addr null_addrp = {{ 0 }};
static enum reply_type force_next_DNS_reply = REPLY_UNKNOWN;
static int last_regex_idx = -1;
static struct ptr_record *pihole_ptr = NULL;

// Fork-private copy of the interface name the most recent query came from
// Fork-private copy of the interface data the most recent query came from
static struct {
char name[IFNAMSIZ];
union all_addr addr4;
Expand Down Expand Up @@ -192,6 +194,16 @@ size_t _FTL_make_answer(struct dns_header *header, char *limit, const size_t len
if(config.debug & DEBUG_FLAGS)
logg("Forced DNS reply to NXDOMAIN");
}
else if(force_next_DNS_reply == REPLY_NODATA)
{
flags = F_NOERR;
// Reset DNS reply forcing
force_next_DNS_reply = REPLY_UNKNOWN;

// Debug logging
if(config.debug & DEBUG_FLAGS)
logg("Forced DNS reply to NODATA");
}
else if(force_next_DNS_reply == REPLY_REFUSED)
{
// Empty flags result in REFUSED
Expand Down Expand Up @@ -237,7 +249,7 @@ size_t _FTL_make_answer(struct dns_header *header, char *limit, const size_t len
{
// If we block in NXDOMAIN mode, we add the NEGATIVE response
// and the NXDOMAIN flags
flags = F_NEG | F_NXDOMAIN;
flags = F_NXDOMAIN;
if(config.debug & DEBUG_FLAGS)
logg("Configured blocking mode is NXDOMAIN");
}
Expand All @@ -253,6 +265,20 @@ size_t _FTL_make_answer(struct dns_header *header, char *limit, const size_t len
}
}

// Check for regex redirecting
bool redirecting = false;
union all_addr redirect_addr4 = {{ 0 }}, redirect_addr6 = {{ 0 }};
if(last_regex_idx > -1)
{
redirecting = regex_get_redirect(last_regex_idx, &redirect_addr4.addr4, &redirect_addr6.addr6);
// Reset regex redirection forcing
last_regex_idx = -1;

// Debug logging
if(config.debug & DEBUG_FLAGS)
logg("Regex match is %sredirected", redirecting ? "" : "NOT ");
}

// Debug logging
if(config.debug & DEBUG_FLAGS)
print_flags(flags);
Expand All @@ -274,13 +300,15 @@ size_t _FTL_make_answer(struct dns_header *header, char *limit, const size_t len
// Add A answer record if requested
if(flags & F_IPV4)
{
union all_addr *addr;
if(config.blockingmode == MODE_IP ||
config.blockingmode == MODE_IP_NODATA_AAAA ||
forced_ip)
union all_addr *addr = &null_addrp;

// Overwrite with IP address if requested
if(redirecting)
addr = &redirect_addr4;
else if(config.blockingmode == MODE_IP ||
config.blockingmode == MODE_IP_NODATA_AAAA ||
forced_ip)
addr = &next_iface.addr4;
else
addr = &null_addrp;

// Debug logging
if(config.debug & DEBUG_QUERIES)
Expand All @@ -301,12 +329,14 @@ size_t _FTL_make_answer(struct dns_header *header, char *limit, const size_t len
// Add AAAA answer record if requested
if(flags & F_IPV6)
{
union all_addr *addr;
if(config.blockingmode == MODE_IP ||
forced_ip)
union all_addr *addr = &null_addrp;

// Overwrite with IP address if requested
if(redirecting)
addr = &redirect_addr6;
else if(config.blockingmode == MODE_IP ||
forced_ip)
addr = &next_iface.addr6;
else
addr = &null_addrp;

// Debug logging
if(config.debug & DEBUG_QUERIES)
Expand Down Expand Up @@ -953,6 +983,13 @@ static bool check_domain_blocked(const char *domain, const int clientID,
set_dnscache_blockingstatus(dns_cache, client, REGEX_BLOCKED, domain);
dns_cache->black_regex_idx = regex_idx;

// Regex may be overwriting reply type for this domain
if(dns_cache->force_reply != REPLY_UNKNOWN)
force_next_DNS_reply = dns_cache->force_reply;

// Store ID of this regex (fork-private)
last_regex_idx = regex_idx;

// We block this domain
return true;
}
Expand Down Expand Up @@ -1089,6 +1126,7 @@ static bool _FTL_check_blocking(int queryID, int domainID, int clientID, const c
if(!query->flags.whitelisted)
{
force_next_DNS_reply = dns_cache->force_reply;
last_regex_idx = dns_cache->black_regex_idx;
query_blocked(query, domain, client, QUERY_REGEX);
return true;
}
Expand Down Expand Up @@ -1207,6 +1245,9 @@ static bool _FTL_check_blocking(int queryID, int domainID, int clientID, const c
// Debug output
if(config.debug & DEBUG_QUERIES)
logg("Blocking %s as %s is %s", domainstr, blockedDomain, blockingreason);

if(force_next_DNS_reply != 0)
logg("Forcing next reply to %s", reply_status_str[force_next_DNS_reply]);
}
else if(db_okay)
{
Expand Down Expand Up @@ -2276,8 +2317,10 @@ static void _query_set_reply(const unsigned int flags, const union all_addr *add
const char *file, const int line)
{
// Iterate through possible values
if(flags & F_NEG || force_next_DNS_reply == REPLY_NXDOMAIN ||
(flags & F_NOERR && !(flags & (F_IPV4 | F_IPV6)))) // <-- FTL_make_answer() when no A or AAAA is added
if(flags & F_NEG ||
(flags & F_NOERR && !(flags & (F_IPV4 | F_IPV6))) || // <-- FTL_make_answer() when no A or AAAA is added
force_next_DNS_reply == REPLY_NXDOMAIN ||
force_next_DNS_reply == REPLY_NODATA)
{
if(flags & F_NXDOMAIN || force_next_DNS_reply == REPLY_NXDOMAIN)
// NXDOMAIN
Expand Down