mirror of
https://github.com/vincentmli/bpfire.git
synced 2026-04-28 11:43:25 +02:00
193 lines
6.8 KiB
Diff
193 lines
6.8 KiB
Diff
From 32fc6dbe03569d70dd394420ceb73532cf303c33 Mon Sep 17 00:00:00 2001
|
|
From: Glen Huang <curvedmark@gmail.com>
|
|
Date: Sat, 27 Dec 2014 15:28:12 +0000
|
|
Subject: [PATCH 21/71] Add --ignore-address option.
|
|
|
|
---
|
|
CHANGELOG | 8 ++++++++
|
|
man/dnsmasq.8 | 6 ++++++
|
|
src/dnsmasq.h | 3 ++-
|
|
src/forward.c | 4 ++++
|
|
src/option.c | 18 +++++++++++++++---
|
|
src/rfc1035.c | 37 +++++++++++++++++++++++++++++++++++++
|
|
6 files changed, 72 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/CHANGELOG b/CHANGELOG
|
|
index 956b71a151db..2b6356bcfb02 100644
|
|
--- a/CHANGELOG
|
|
+++ b/CHANGELOG
|
|
@@ -22,6 +22,14 @@ version 2.73
|
|
|
|
Fix crash in DNSSEC code with long RRs. Thanks to Marco Davids
|
|
for the bug report.
|
|
+
|
|
+ Add --ignore-address option. Ignore replies to A-record
|
|
+ queries which include the specified address. No error is
|
|
+ generated, dnsmasq simply continues to listen for another
|
|
+ reply. This is useful to defeat blocking strategies which
|
|
+ rely on quickly supplying a forged answer to a DNS
|
|
+ request for certain domains, before the correct answer can
|
|
+ arrive. Thanks to Glen Huang for the patch.
|
|
|
|
|
|
version 2.72
|
|
diff --git a/man/dnsmasq.8 b/man/dnsmasq.8
|
|
index 0b8e04f0a897..4236ba307df3 100644
|
|
--- a/man/dnsmasq.8
|
|
+++ b/man/dnsmasq.8
|
|
@@ -293,6 +293,12 @@ an advertising web page in response to queries for unregistered names,
|
|
instead of the correct NXDOMAIN response. This option tells dnsmasq to
|
|
fake the correct response when it sees this behaviour. As at Sept 2003
|
|
the IP address being returned by Verisign is 64.94.110.11
|
|
+.TP
|
|
+.B \-B, --ignore-address=<ipaddr>
|
|
+Ignore replies to A-record queries which include the specified address.
|
|
+No error is generated, dnsmasq simply continues to listen for another reply.
|
|
+This is useful to defeat blocking strategies which rely on quickly supplying a
|
|
+forged answer to a DNS request for certain domain, before the correct answer can arrive.
|
|
.TP
|
|
.B \-f, --filterwin2k
|
|
Later versions of windows make periodic DNS requests which don't get sensible answers from
|
|
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
|
|
index 1dd61c5edba3..7bc982ddf73c 100644
|
|
--- a/src/dnsmasq.h
|
|
+++ b/src/dnsmasq.h
|
|
@@ -930,7 +930,7 @@ extern struct daemon {
|
|
char *runfile;
|
|
char *lease_change_command;
|
|
struct iname *if_names, *if_addrs, *if_except, *dhcp_except, *auth_peers, *tftp_interfaces;
|
|
- struct bogus_addr *bogus_addr;
|
|
+ struct bogus_addr *bogus_addr, *ignore_addr;
|
|
struct server *servers;
|
|
struct ipsets *ipsets;
|
|
int log_fac; /* log facility */
|
|
@@ -1093,6 +1093,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|
time_t now, int *ad_reqd, int *do_bit);
|
|
int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
|
|
struct bogus_addr *addr, time_t now);
|
|
+int check_for_ignored_address(struct dns_header *header, size_t qlen, struct bogus_addr *baddr);
|
|
unsigned char *find_pseudoheader(struct dns_header *header, size_t plen,
|
|
size_t *len, unsigned char **p, int *is_sign);
|
|
int check_for_local_domain(char *name, time_t now);
|
|
diff --git a/src/forward.c b/src/forward.c
|
|
index 408a179a20f4..f28c7d51f708 100644
|
|
--- a/src/forward.c
|
|
+++ b/src/forward.c
|
|
@@ -724,6 +724,10 @@ void reply_query(int fd, int family, time_t now)
|
|
if (!(forward = lookup_frec(ntohs(header->id), hash)))
|
|
return;
|
|
|
|
+ if (daemon->ignore_addr && RCODE(header) == NOERROR &&
|
|
+ check_for_ignored_address(header, n, daemon->ignore_addr))
|
|
+ return;
|
|
+
|
|
if ((RCODE(header) == SERVFAIL || RCODE(header) == REFUSED) &&
|
|
!option_bool(OPT_ORDER) &&
|
|
forward->forwardall == 0)
|
|
diff --git a/src/option.c b/src/option.c
|
|
index 209fa6976609..907d0cf88de9 100644
|
|
--- a/src/option.c
|
|
+++ b/src/option.c
|
|
@@ -147,6 +147,7 @@ struct myoption {
|
|
#define LOPT_LOCAL_SERVICE 335
|
|
#define LOPT_DNSSEC_TIME 336
|
|
#define LOPT_LOOP_DETECT 337
|
|
+#define LOPT_IGNORE_ADDR 338
|
|
|
|
#ifdef HAVE_GETOPT_LONG
|
|
static const struct option opts[] =
|
|
@@ -181,6 +182,7 @@ static const struct myoption opts[] =
|
|
{ "local-service", 0, 0, LOPT_LOCAL_SERVICE },
|
|
{ "bogus-priv", 0, 0, 'b' },
|
|
{ "bogus-nxdomain", 1, 0, 'B' },
|
|
+ { "ignore-address", 1, 0, LOPT_IGNORE_ADDR },
|
|
{ "selfmx", 0, 0, 'e' },
|
|
{ "filterwin2k", 0, 0, 'f' },
|
|
{ "pid-file", 2, 0, 'x' },
|
|
@@ -457,6 +459,7 @@ static struct {
|
|
{ LOPT_QUIET_RA, OPT_QUIET_RA, NULL, gettext_noop("Do not log RA."), NULL },
|
|
{ LOPT_LOCAL_SERVICE, OPT_LOCAL_SERVICE, NULL, gettext_noop("Accept queries only from directly-connected networks"), NULL },
|
|
{ LOPT_LOOP_DETECT, OPT_LOOP_DETECT, NULL, gettext_noop("Detect and remove DNS forwarding loops"), NULL },
|
|
+ { LOPT_IGNORE_ADDR, ARG_DUP, "<ipaddr>", gettext_noop("Ignore DNS responses containing ipaddr."), NULL },
|
|
{ 0, 0, NULL, NULL, NULL }
|
|
};
|
|
|
|
@@ -2119,14 +2122,23 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|
break;
|
|
|
|
case 'B': /* --bogus-nxdomain */
|
|
- {
|
|
+ case LOPT_IGNORE_ADDR: /* --ignore-address */
|
|
+ {
|
|
struct in_addr addr;
|
|
unhide_metas(arg);
|
|
if (arg && (inet_pton(AF_INET, arg, &addr) > 0))
|
|
{
|
|
struct bogus_addr *baddr = opt_malloc(sizeof(struct bogus_addr));
|
|
- baddr->next = daemon->bogus_addr;
|
|
- daemon->bogus_addr = baddr;
|
|
+ if (option == 'B')
|
|
+ {
|
|
+ baddr->next = daemon->bogus_addr;
|
|
+ daemon->bogus_addr = baddr;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ baddr->next = daemon->ignore_addr;
|
|
+ daemon->ignore_addr = baddr;
|
|
+ }
|
|
baddr->addr = addr;
|
|
}
|
|
else
|
|
diff --git a/src/rfc1035.c b/src/rfc1035.c
|
|
index bdeb3fb10e68..75c4266b47dd 100644
|
|
--- a/src/rfc1035.c
|
|
+++ b/src/rfc1035.c
|
|
@@ -1328,6 +1328,43 @@ int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
|
|
return 0;
|
|
}
|
|
|
|
+int check_for_ignored_address(struct dns_header *header, size_t qlen, struct bogus_addr *baddr)
|
|
+{
|
|
+ unsigned char *p;
|
|
+ int i, qtype, qclass, rdlen;
|
|
+ struct bogus_addr *baddrp;
|
|
+
|
|
+ /* skip over questions */
|
|
+ if (!(p = skip_questions(header, qlen)))
|
|
+ return 0; /* bad packet */
|
|
+
|
|
+ for (i = ntohs(header->ancount); i != 0; i--)
|
|
+ {
|
|
+ if (!(p = skip_name(p, header, qlen, 10)))
|
|
+ return 0; /* bad packet */
|
|
+
|
|
+ GETSHORT(qtype, p);
|
|
+ GETSHORT(qclass, p);
|
|
+ p += 4; /* TTL */
|
|
+ GETSHORT(rdlen, p);
|
|
+
|
|
+ if (qclass == C_IN && qtype == T_A)
|
|
+ {
|
|
+ if (!CHECK_LEN(header, p, qlen, INADDRSZ))
|
|
+ return 0;
|
|
+
|
|
+ for (baddrp = baddr; baddrp; baddrp = baddrp->next)
|
|
+ if (memcmp(&baddrp->addr, p, INADDRSZ) == 0)
|
|
+ return 1;
|
|
+ }
|
|
+
|
|
+ if (!ADD_RDLEN(header, p, qlen, rdlen))
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
int add_resource_record(struct dns_header *header, char *limit, int *truncp, int nameoffset, unsigned char **pp,
|
|
unsigned long ttl, int *offset, unsigned short type, unsigned short class, char *format, ...)
|
|
{
|
|
--
|
|
2.1.0
|
|
|