]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
3790. [bug] Handle broken nameservers that send BADVERS in
authorMark Andrews <marka@isc.org>
Wed, 19 Mar 2014 18:00:55 +0000 (05:00 +1100)
committerMark Andrews <marka@isc.org>
Wed, 19 Mar 2014 18:00:55 +0000 (05:00 +1100)
                        response to unknown EDNS options.  Maintain
                        statistics on BADVERS responses.

CHANGES
bin/named/statschannel.c
lib/dns/include/dns/stats.h
lib/dns/resolver.c

diff --git a/CHANGES b/CHANGES
index e9109cb936d9cdd61681876d08f3174004633c6a..6ae93e72adcde539cc041db2c522c945430c43f8 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,7 @@
+3790.  [bug]           Handle broken nameservers that send BADVERS in
+                       response to unknown EDNS options.  Maintain
+                       statistics on BADVERS responses.
+
 3789.  [bug]           Null pointer dereference on rbt creation failure.
 
 3788.  [bug]           dns_peer_getrequestsit was returning request_nsid by
index 6052308477f7796fa412dc8db44e87582be87bb5..0764aa75b23b106348a084db9af8adaa8fc7bbf0 100644 (file)
@@ -319,6 +319,7 @@ init_desc(void) {
        SET_RESSTATDESC(sitin, "SIT replies received", "SitIn");
        SET_RESSTATDESC(sitok, "SIT client cookie ok", "SitClientOk");
 #endif
+       SET_RESSTATDESC(badvers, "bad EDNS version", "BadEDNSVersion");
 
        INSIST(i == dns_resstatscounter_max);
 
index 059dcd487f77262409292e95d90f68ad7b625660..534da4df4f8edd5c52358c3f837eb9b052f3309e 100644 (file)
@@ -72,9 +72,11 @@ enum {
        dns_resstatscounter_sitin = 37,
        dns_resstatscounter_sitok = 38,
 
-       dns_resstatscounter_max = 39,
+       dns_resstatscounter_badvers = 39,
+       dns_resstatscounter_max = 40,
 #else
-       dns_resstatscounter_max = 35,
+       dns_resstatscounter_badvers = 35,
+       dns_resstatscounter_max = 36,
 #endif
 
        /*
index 676d54817c35a4c784a70e45eedac52379e0da94..068d0ced4eb3593ab04074aca02729ce1db0cf1f 100644 (file)
@@ -459,13 +459,14 @@ struct dns_resolver {
 #define VALID_RESOLVER(res)            ISC_MAGIC_VALID(res, RES_MAGIC)
 
 /*%
- * Private addrinfo flags.  These must not conflict with DNS_FETCHOPT_NOEDNS0,
- * which we also use as an addrinfo flag.
+ * Private addrinfo flags.  These must not conflict with DNS_FETCHOPT_NOEDNS0
+ * (0x008) which we also use as an addrinfo flag.
  */
 #define FCTX_ADDRINFO_MARK              0x0001
 #define FCTX_ADDRINFO_FORWARDER         0x1000
 #define FCTX_ADDRINFO_TRIED             0x2000
 #define FCTX_ADDRINFO_EDNSOK            0x4000
+#define FCTX_ADDRINFO_NOSIT             0x8000
 
 #define UNMARKED(a)                     (((a)->flags & FCTX_ADDRINFO_MARK) \
                                         == 0)
@@ -473,6 +474,8 @@ struct dns_resolver {
                                         FCTX_ADDRINFO_FORWARDER) != 0)
 #define TRIED(a)                        (((a)->flags & \
                                         FCTX_ADDRINFO_TRIED) != 0)
+#define NOSIT(a)                        (((a)->flags & \
+                                        FCTX_ADDRINFO_NOSIT) != 0)
 
 #define NXDOMAIN(r) (((r)->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)
 #define NEGATIVE(r) (((r)->attributes & DNS_RDATASETATTR_NEGATIVE) != 0)
@@ -2063,6 +2066,10 @@ resquery_send(resquery_t *query) {
                                (void) dns_peer_getrequestsit(peer, &reqsit);
 #endif
                        }
+#ifdef ISC_PLATFORM_USESIT
+                       if (NOSIT(query->addrinfo))
+                               reqsit = ISC_FALSE;
+#endif
                        if (reqnsid) {
                                INSIST(ednsopt < DNS_EDNSOPTIONS);
                                ednsopts[ednsopt].code = DNS_OPT_NSID;
@@ -7499,6 +7506,19 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
                        unsigned int flags, mask;
                        unsigned int version;
 
+                       inc_stats(fctx->res, dns_resstatscounter_badvers);
+
+#ifdef ISC_PLATFORM_USESIT
+                       /*
+                        * Some servers return BADVERS to unknown
+                        * EDNS options.  This cannot be long term
+                        * strategy.
+                        */
+                       dns_adb_changeflags(fctx->adb, query->addrinfo,
+                                           FCTX_ADDRINFO_NOSIT,
+                                           FCTX_ADDRINFO_NOSIT);
+#endif
+
                        resend = ISC_TRUE;
                        INSIST(opt != NULL);
                        version = (opt->ttl >> 16) & 0xff;