diff --git a/CMakeLists.txt b/CMakeLists.txt index 99b5ffe2..ba4f75cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,6 @@ cmake_minimum_required(VERSION 2.8.12) project(PIHOLE_FTL C) -set(DNSMASQ_VERSION pi-hole-2.83) +set(DNSMASQ_VERSION pi-hole-2.84) add_subdirectory(src) diff --git a/src/dnsmasq/arp.c b/src/dnsmasq/arp.c index 3329d6d6..2503ce49 100644 --- a/src/dnsmasq/arp.c +++ b/src/dnsmasq/arp.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/auth.c b/src/dnsmasq/auth.c index b2fcd4b6..d0263b16 100644 --- a/src/dnsmasq/auth.c +++ b/src/dnsmasq/auth.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/blockdata.c b/src/dnsmasq/blockdata.c index f33b28e8..dc818837 100644 --- a/src/dnsmasq/blockdata.c +++ b/src/dnsmasq/blockdata.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/bpf.c b/src/dnsmasq/bpf.c index 0ac1c8fd..82d215a9 100644 --- a/src/dnsmasq/bpf.c +++ b/src/dnsmasq/bpf.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/cache.c b/src/dnsmasq/cache.c index 00bdb36c..39b440bf 100644 --- a/src/dnsmasq/cache.c +++ b/src/dnsmasq/cache.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/config.h b/src/dnsmasq/config.h index 2c4eb3a4..4e885e5c 100644 --- a/src/dnsmasq/config.h +++ b/src/dnsmasq/config.h @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -122,8 +122,8 @@ HAVE_AUTH define this to include the facility to act as an authoritative DNS server for one or more zones. -HAVE_NETTLEHASH - include just hash function from nettle, but no DNSSEC. +HAVE_CRYPTOHASH + include just hash function from crypto library, but no DNSSEC. HAVE_DNSSEC include DNSSEC validator. @@ -192,7 +192,7 @@ RESOLVFILE /* #define HAVE_IDN */ /* #define HAVE_LIBIDN2 */ /* #define HAVE_CONNTRACK */ -/* #define HAVE_NETTLEHASH */ +/* #define HAVE_CRYPTOHASH */ /* #define HAVE_DNSSEC */ @@ -426,10 +426,10 @@ static char *compile_opts = "no-" #endif "auth " -#if !defined(HAVE_NETTLEHASH) && !defined(HAVE_DNSSEC) +#if !defined(HAVE_CRYPTOHASH) && !defined(HAVE_DNSSEC) "no-" #endif -"nettlehash " +"cryptohash " #ifndef HAVE_DNSSEC "no-" #endif diff --git a/src/dnsmasq/conntrack.c b/src/dnsmasq/conntrack.c index 33f5ceb5..7ec20833 100644 --- a/src/dnsmasq/conntrack.c +++ b/src/dnsmasq/conntrack.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/crypto.c b/src/dnsmasq/crypto.c index 09525d2f..9e83719d 100644 --- a/src/dnsmasq/crypto.c +++ b/src/dnsmasq/crypto.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -27,7 +27,7 @@ #endif #endif -#if defined(HAVE_DNSSEC) || defined(HAVE_NETTLEHASH) +#if defined(HAVE_DNSSEC) || defined(HAVE_CRYPTOHASH) #include #include diff --git a/src/dnsmasq/dbus.c b/src/dnsmasq/dbus.c index 6def1296..2516483b 100644 --- a/src/dnsmasq/dbus.c +++ b/src/dnsmasq/dbus.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/dhcp-common.c b/src/dnsmasq/dhcp-common.c index 2c5c316f..480ed225 100644 --- a/src/dnsmasq/dhcp-common.c +++ b/src/dnsmasq/dhcp-common.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/dhcp-protocol.h b/src/dnsmasq/dhcp-protocol.h index e9007c87..6ff3ffa2 100644 --- a/src/dnsmasq/dhcp-protocol.h +++ b/src/dnsmasq/dhcp-protocol.h @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/dhcp.c b/src/dnsmasq/dhcp.c index bea46881..97324f23 100644 --- a/src/dnsmasq/dhcp.c +++ b/src/dnsmasq/dhcp.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/dhcp6-protocol.h b/src/dnsmasq/dhcp6-protocol.h index 48b027b0..5277c22c 100644 --- a/src/dnsmasq/dhcp6-protocol.h +++ b/src/dnsmasq/dhcp6-protocol.h @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/dhcp6.c b/src/dnsmasq/dhcp6.c index 096e2e17..9901e1bb 100644 --- a/src/dnsmasq/dhcp6.c +++ b/src/dnsmasq/dhcp6.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/dns-protocol.h b/src/dnsmasq/dns-protocol.h index 8edb9f3f..941bea6a 100644 --- a/src/dnsmasq/dns-protocol.h +++ b/src/dnsmasq/dns-protocol.h @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/dnsmasq.c b/src/dnsmasq/dnsmasq.c index 04007aae..e76851c2 100644 --- a/src/dnsmasq/dnsmasq.c +++ b/src/dnsmasq/dnsmasq.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -392,8 +392,8 @@ int main_dnsmasq (int argc, char **argv) if (daemon->port != 0) { cache_init(); - blockdata_init(); + hash_questions_init(); } #ifdef HAVE_INOTIFY diff --git a/src/dnsmasq/dnsmasq.h b/src/dnsmasq/dnsmasq.h index 2522a406..dbb0db52 100644 --- a/src/dnsmasq/dnsmasq.h +++ b/src/dnsmasq/dnsmasq.h @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -14,7 +14,7 @@ along with this program. If not, see . */ -#define COPYRIGHT "Copyright (c) 2000-2020 Simon Kelley" +#define COPYRIGHT "Copyright (c) 2000-2021 Simon Kelley" /* We do defines that influence behavior of stdio.h, so complain if included too early. */ @@ -157,7 +157,11 @@ extern int capget(cap_user_header_t header, cap_user_data_t data); #include #endif -#if defined(HAVE_DNSSEC) || defined(HAVE_NETTLEHASH) +/* Backwards compat with 2.83 */ +#if defined(HAVE_NETTLEHASH) +# define HAVE_CRYPTOHASH +#endif +#if defined(HAVE_DNSSEC) || defined(HAVE_CRYPTOHASH) # include #endif @@ -666,6 +670,7 @@ struct frec { union mysockaddr source; union all_addr dest; unsigned int iface, log_id; + int fd; unsigned short orig_id; struct frec_src *next; } frec_src; @@ -673,7 +678,7 @@ struct frec { struct randfd *rfd4; struct randfd *rfd6; unsigned short new_id; - int fd, forwardall, flags; + int forwardall, flags; time_t time; unsigned char *hash[HASH_SIZE]; #ifdef HAVE_DNSSEC @@ -1265,6 +1270,7 @@ size_t filter_rrsigs(struct dns_header *header, size_t plen); int setup_timestamp(void); /* hash_questions.c */ +void hash_questions_init(void); unsigned char *hash_questions(struct dns_header *header, size_t plen, char *name); /* crypto.c */ diff --git a/src/dnsmasq/dnssec.c b/src/dnsmasq/dnssec.c index 93cc7bf1..3ee1e9eb 100644 --- a/src/dnsmasq/dnssec.c +++ b/src/dnsmasq/dnssec.c @@ -334,37 +334,64 @@ static int sort_rrset(struct dns_header *header, size_t plen, u16 *rr_desc, int if (!CHECK_LEN(header, state2.ip, plen, rdlen2)) return rrsetidx; /* short packet */ state2.end = state2.ip + rdlen2; - - while (1) - { - int ok1, ok2; - - ok1 = get_rdata(header, plen, &state1); - ok2 = get_rdata(header, plen, &state2); - if (!ok1 && !ok2) + /* If the RR has no names in it then canonicalisation + is the identity function and we can compare + the RRs directly. If not we compare the + canonicalised RRs one byte at a time. */ + if (*rr_desc == (u16)-1) + { + int rdmin = rdlen1 > rdlen2 ? rdlen2 : rdlen1; + int cmp = memcmp(state1.ip, state2.ip, rdmin); + + if (cmp > 0 || (cmp == 0 && rdlen1 > rdmin)) + { + unsigned char *tmp = rrset[i+1]; + rrset[i+1] = rrset[i]; + rrset[i] = tmp; + swap = 1; + } + else if (cmp == 0 && (rdlen1 == rdlen2)) { /* Two RRs are equal, remove one copy. RFC 4034, para 6.3 */ for (j = i+1; j < rrsetidx-1; j++) rrset[j] = rrset[j+1]; rrsetidx--; i--; - break; } - else if (ok1 && (!ok2 || *state1.op > *state2.op)) - { - unsigned char *tmp = rrset[i+1]; - rrset[i+1] = rrset[i]; - rrset[i] = tmp; - swap = 1; - break; - } - else if (ok2 && (!ok1 || *state2.op > *state1.op)) - break; - - /* arrive here when bytes are equal, go round the loop again - and compare the next ones. */ } + else + /* Comparing canonicalised RRs, byte-at-a-time. */ + while (1) + { + int ok1, ok2; + + ok1 = get_rdata(header, plen, &state1); + ok2 = get_rdata(header, plen, &state2); + + if (!ok1 && !ok2) + { + /* Two RRs are equal, remove one copy. RFC 4034, para 6.3 */ + for (j = i+1; j < rrsetidx-1; j++) + rrset[j] = rrset[j+1]; + rrsetidx--; + i--; + break; + } + else if (ok1 && (!ok2 || *state1.op > *state2.op)) + { + unsigned char *tmp = rrset[i+1]; + rrset[i+1] = rrset[i]; + rrset[i] = tmp; + swap = 1; + break; + } + else if (ok2 && (!ok1 || *state2.op > *state1.op)) + break; + + /* arrive here when bytes are equal, go round the loop again + and compare the next ones. */ + } } } while (swap); diff --git a/src/dnsmasq/domain.c b/src/dnsmasq/domain.c index 3dc96abc..189bdd15 100644 --- a/src/dnsmasq/domain.c +++ b/src/dnsmasq/domain.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/dump.c b/src/dnsmasq/dump.c index 9bd3a5f9..c131953a 100644 --- a/src/dnsmasq/dump.c +++ b/src/dnsmasq/dump.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/edns0.c b/src/dnsmasq/edns0.c index 53cfe240..c85b3188 100644 --- a/src/dnsmasq/edns0.c +++ b/src/dnsmasq/edns0.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/forward.c b/src/dnsmasq/forward.c index 5deb386b..035d8482 100644 --- a/src/dnsmasq/forward.c +++ b/src/dnsmasq/forward.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -391,8 +391,12 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr, new->dest = *dst_addr; new->log_id = daemon->log_id; new->iface = dst_iface; + new->fd = udpfd; } + // Pi-hole modification + FTL_query_in_progress(daemon->log_id); + return 1; } @@ -415,8 +419,8 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr, forward->frec_src.dest = *dst_addr; forward->frec_src.iface = dst_iface; forward->frec_src.next = NULL; + forward->frec_src.fd = udpfd; forward->new_id = get_id(); - forward->fd = udpfd; memcpy(forward->hash, hash, HASH_SIZE); forward->forwardall = 0; forward->flags = fwd_flags; @@ -1329,6 +1333,9 @@ void reply_query(int fd, int family, time_t now) } #endif + // Pi-hole modification + int first_ID = -1; + for (src = &forward->frec_src; src; src = src->next) { header->id = htons(src->orig_id); @@ -1337,7 +1344,7 @@ void reply_query(int fd, int family, time_t now) dump_packet(DUMP_REPLY, daemon->packet, (size_t)nn, NULL, &src->source); #endif - send_from(forward->fd, option_bool(OPT_NOWILD) || option_bool (OPT_CLEVERBIND), daemon->packet, nn, + send_from(src->fd, option_bool(OPT_NOWILD) || option_bool (OPT_CLEVERBIND), daemon->packet, nn, &src->source, &src->dest, src->iface); if (option_bool(OPT_EXTRALOG) && src != &forward->frec_src) @@ -1346,6 +1353,8 @@ void reply_query(int fd, int family, time_t now) daemon->log_source_addr = &src->source; log_query(F_UPSTREAM, "query", NULL, "duplicate"); } + /* Pi-hole modification */ + FTL_duplicate_reply(src->log_id, &first_ID); } } diff --git a/src/dnsmasq/hash_questions.c b/src/dnsmasq/hash_questions.c index 51d88c28..8e1559ff 100644 --- a/src/dnsmasq/hash_questions.c +++ b/src/dnsmasq/hash_questions.c @@ -28,28 +28,28 @@ #include "dnsmasq.h" -#if defined(HAVE_DNSSEC) || defined(HAVE_NETTLEHASH) +#if defined(HAVE_DNSSEC) || defined(HAVE_CRYPTOHASH) + +static const struct nettle_hash *hash; +static void *ctx; +static unsigned char *digest; + +void hash_questions_init(void) +{ + if (!(hash = hash_find("sha256"))) + die(_("Failed to create SHA-256 hash object"), NULL, EC_MISC); + + ctx = safe_malloc(hash->context_size); + digest = safe_malloc(hash->digest_size); +} + unsigned char *hash_questions(struct dns_header *header, size_t plen, char *name) { int q; unsigned char *p = (unsigned char *)(header+1); - const struct nettle_hash *hash; - void *ctx; - unsigned char *digest; - - if (!(hash = hash_find("sha256")) || !hash_init(hash, &ctx, &digest)) - { - /* don't think this can ever happen. */ - static unsigned char dummy[HASH_SIZE]; - static int warned = 0; - if (!warned) - my_syslog(LOG_ERR, _("Failed to create SHA-256 hash object")); - warned = 1; - - return dummy; - } - + hash->init(ctx); + for (q = ntohs(header->qdcount); q != 0; q--) { char *cp, c; @@ -74,7 +74,7 @@ unsigned char *hash_questions(struct dns_header *header, size_t plen, char *name return digest; } -#else /* HAVE_DNSSEC */ +#else /* HAVE_DNSSEC || HAVE_CRYPTOHASH */ #define SHA256_BLOCK_SIZE 32 // SHA256 outputs a 32 byte digest typedef unsigned char BYTE; // 8-bit byte @@ -91,6 +91,9 @@ static void sha256_init(SHA256_CTX *ctx); static void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len); static void sha256_final(SHA256_CTX *ctx, BYTE hash[]); +void hash_questions_init(void) +{ +} unsigned char *hash_questions(struct dns_header *header, size_t plen, char *name) { diff --git a/src/dnsmasq/helper.c b/src/dnsmasq/helper.c index 8cfa1c42..ac0412fd 100644 --- a/src/dnsmasq/helper.c +++ b/src/dnsmasq/helper.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/inotify.c b/src/dnsmasq/inotify.c index d5804cbc..b87798b0 100644 --- a/src/dnsmasq/inotify.c +++ b/src/dnsmasq/inotify.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/ip6addr.h b/src/dnsmasq/ip6addr.h index 352b3300..c00dd08e 100644 --- a/src/dnsmasq/ip6addr.h +++ b/src/dnsmasq/ip6addr.h @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/lease.c b/src/dnsmasq/lease.c index 23e6fe0a..ecfe7c3a 100644 --- a/src/dnsmasq/lease.c +++ b/src/dnsmasq/lease.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/log.c b/src/dnsmasq/log.c index 85a5f3fd..5ea72bf4 100644 --- a/src/dnsmasq/log.c +++ b/src/dnsmasq/log.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/loop.c b/src/dnsmasq/loop.c index 78e1238d..15e34c71 100644 --- a/src/dnsmasq/loop.c +++ b/src/dnsmasq/loop.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/metrics.c b/src/dnsmasq/metrics.c index 79f20b0d..fac5b005 100644 --- a/src/dnsmasq/metrics.c +++ b/src/dnsmasq/metrics.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/metrics.h b/src/dnsmasq/metrics.h index ccc92a86..cecf8c83 100644 --- a/src/dnsmasq/metrics.h +++ b/src/dnsmasq/metrics.h @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/netlink.c b/src/dnsmasq/netlink.c index 8e8431fa..04940707 100644 --- a/src/dnsmasq/netlink.c +++ b/src/dnsmasq/netlink.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/network.c b/src/dnsmasq/network.c index 323d446c..8073cabf 100644 --- a/src/dnsmasq/network.c +++ b/src/dnsmasq/network.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/option.c b/src/dnsmasq/option.c index 2e61f4fb..2c50a2a7 100644 --- a/src/dnsmasq/option.c +++ b/src/dnsmasq/option.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/outpacket.c b/src/dnsmasq/outpacket.c index 50513dc3..da6f73cb 100644 --- a/src/dnsmasq/outpacket.c +++ b/src/dnsmasq/outpacket.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/poll.c b/src/dnsmasq/poll.c index 24d01bb1..f4146905 100644 --- a/src/dnsmasq/poll.c +++ b/src/dnsmasq/poll.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/radv-protocol.h b/src/dnsmasq/radv-protocol.h index edc15327..dccd4e1e 100644 --- a/src/dnsmasq/radv-protocol.h +++ b/src/dnsmasq/radv-protocol.h @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/radv.c b/src/dnsmasq/radv.c index 41df852e..3255904b 100644 --- a/src/dnsmasq/radv.c +++ b/src/dnsmasq/radv.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/rfc1035.c b/src/dnsmasq/rfc1035.c index 013fbf14..d24f9faa 100644 --- a/src/dnsmasq/rfc1035.c +++ b/src/dnsmasq/rfc1035.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/rfc2131.c b/src/dnsmasq/rfc2131.c index d6780685..3f507550 100644 --- a/src/dnsmasq/rfc2131.c +++ b/src/dnsmasq/rfc2131.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/rfc3315.c b/src/dnsmasq/rfc3315.c index b3f0a0a0..982c68a7 100644 --- a/src/dnsmasq/rfc3315.c +++ b/src/dnsmasq/rfc3315.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/rrfilter.c b/src/dnsmasq/rrfilter.c index 16e6b554..58c6d8ff 100644 --- a/src/dnsmasq/rrfilter.c +++ b/src/dnsmasq/rrfilter.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/slaac.c b/src/dnsmasq/slaac.c index 4a3e01d2..9b100630 100644 --- a/src/dnsmasq/slaac.c +++ b/src/dnsmasq/slaac.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/tftp.c b/src/dnsmasq/tftp.c index aa240e5b..846b32e3 100644 --- a/src/dnsmasq/tftp.c +++ b/src/dnsmasq/tftp.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/ubus.c b/src/dnsmasq/ubus.c index 5f812877..33c27832 100644 --- a/src/dnsmasq/ubus.c +++ b/src/dnsmasq/ubus.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq/util.c b/src/dnsmasq/util.c index 5f13027d..972c60b7 100644 --- a/src/dnsmasq/util.c +++ b/src/dnsmasq/util.c @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/dnsmasq_interface.c b/src/dnsmasq_interface.c index f4faac65..eafb3701 100644 --- a/src/dnsmasq_interface.c +++ b/src/dnsmasq_interface.c @@ -2180,3 +2180,110 @@ bool FTL_unlink_DHCP_lease(const char *ipaddr) return true; } + +void FTL_query_in_progress(const int id) +{ + // Query (possibly from new source), but the same query may be in + // progress from another source. + + // Lock shared memory + lock_shm(); + + // Search for corresponding query identified by ID + const int queryID = findQueryID(id); + if(queryID < 0) + { + // This may happen e.g. if the original query was an unhandled query type + unlock_shm(); + return; + } + + // Get query pointer + queriesData* query = getQuery(queryID, true); + if(query == NULL) + { + // Memory error, skip this DNSSEC details + unlock_shm(); + return; + } + + // Debug logging + if(config.debug & DEBUG_QUERIES) + { + // Get domain pointer + const domainsData* domain = getDomain(query->domainID, true); + if(domain != NULL) + { + logg("**** query for %s is already in progress (ID %i)", getstr(domain->domainpos), id); + } + } + + // Store status + query->status = QUERY_IN_PROGRESS; + + // Unlock shared memory + unlock_shm(); +} + +void FTL_duplicate_reply(const int id, int *firstID) +{ + // Reply to duplicated query + + // Check if we can process thes duplicated queries at all + if(*firstID == -2) + return; + + // Lock shared memory + lock_shm(); + + // Search for corresponding query identified by ID + const int queryID = findQueryID(id); + if(queryID < 0) + { + // This may happen e.g. if the original query was an unhandled query type + unlock_shm(); + *firstID = -2; + return; + } + + if(*firstID == -1) + { + // This is not yet a duplicate, we just store the ID + // of the successful reply here so we can get it quicker + // during the next loop iterations + unlock_shm(); + *firstID = queryID; + return; + } + + // Get query pointer of duplicate reply + queriesData* duplicated_query = getQuery(queryID, true); + const queriesData* source_query = getQuery(*firstID, true); + + if(duplicated_query == NULL || source_query == NULL) + { + // Memory error, skip this duplicate + unlock_shm(); + return; + } + + // Debug logging + if(config.debug & DEBUG_QUERIES) + { + logg("**** query %d is duplicate of %d", queryID, *firstID); + } + + // Copy relevant information over + duplicated_query->reply = source_query->reply; + duplicated_query->dnssec = source_query->dnssec; + duplicated_query->flags.complete = true; + + // The original query may have been blocked during CNAME inspection, + // correct status in this case + if(source_query->status != QUERY_FORWARDED) + duplicated_query->status = source_query->status; + duplicated_query->CNAME_domainID = source_query->CNAME_domainID; + + // Unlock shared memory + unlock_shm(); +} diff --git a/src/dnsmasq_interface.h b/src/dnsmasq_interface.h index 7f7d34bf..3b7c4d2c 100644 --- a/src/dnsmasq_interface.h +++ b/src/dnsmasq_interface.h @@ -53,6 +53,8 @@ void _FTL_get_blocking_metadata(union all_addr **addrp, unsigned int *flags, con bool _FTL_CNAME(const char *domain, const struct crec *cpp, const int id, const char* file, const int line); unsigned int FTL_extract_question_flags(struct dns_header *header, const size_t qlen); +void FTL_query_in_progress(const int id); +void FTL_duplicate_reply(const int id, int *firstID); void FTL_dnsmasq_reload(void); void FTL_fork_and_bind_sockets(struct passwd *ent_pw); diff --git a/src/enums.h b/src/enums.h index 314b9bb0..22e43d80 100644 --- a/src/enums.h +++ b/src/enums.h @@ -42,6 +42,7 @@ enum query_status { QUERY_BLACKLIST_CNAME, QUERY_RETRIED, QUERY_RETRIED_DNSSEC, + QUERY_IN_PROGRESS, QUERY_STATUS_MAX } __attribute__ ((packed)); diff --git a/src/gc.c b/src/gc.c index b7960d2d..f29409bf 100644 --- a/src/gc.c +++ b/src/gc.c @@ -128,6 +128,11 @@ void *GC_thread(void *val) if(client != NULL) change_clientcount(client, 0, -1, -1, 0); break; + case QUERY_IN_PROGRESS: + // Nothing to be done here, this was a duplicated query. It + // wasn't forwarded on its own to save some traffic (and + // reduce the attack surface for cache spoofing) + break; case QUERY_STATUS_MAX: // fall through default: /* That cannot happen */