]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
1879. [func] Added framework for handling multiple EDNS versions.
authorMark Andrews <marka@isc.org>
Tue, 7 Jun 2005 00:16:01 +0000 (00:16 +0000)
committerMark Andrews <marka@isc.org>
Tue, 7 Jun 2005 00:16:01 +0000 (00:16 +0000)
1878.   [func]          dig can now specify the EDNS version when making
                        a query.

CHANGES
bin/dig/dig.c
bin/dig/dig.docbook
bin/dig/dighost.c
bin/dig/include/dig/dig.h
bin/named/client.c
bin/named/include/named/client.h
lib/dns/include/dns/resolver.h
lib/dns/resolver.c

diff --git a/CHANGES b/CHANGES
index 0fb5c14aee860009a5195945514359f6bdec49ca..ee880612b64897f583c792c4404d8b961a9a6236 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,8 @@
+1879.  [func]          Added framework for handling multiple EDNS versions.
+
+1878.  [func]          dig can now specify the EDNS version when making
+                       a query.
+
 1868.  [placeholder]   rt14851
 
 1867.  [placeholder]   rt14846
index 96baacbad92d4c8001462533b623e72730ce84f2..df3032c973c3e9bc58ba0fc3497bdf5fe77cda7e 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: dig.c,v 1.203 2005/04/27 04:55:44 sra Exp $ */
+/* $Id: dig.c,v 1.204 2005/06/07 00:15:58 marka Exp $ */
 
 /*! \file */
 
@@ -192,6 +192,7 @@ help(void) {
 "                 +domain=###         (Set default domainname)\n"
 "                 +bufsize=###        (Set EDNS0 Max UDP packet size)\n"
 "                 +ndots=###          (Set NDOTS value)\n"
+"                 +edns=###           (Set EDNS version)\n"
 "                 +[no]search         (Set whether to use searchlist)\n"
 "                 +[no]defname        (Ditto)\n"
 "                 +[no]recurse        (Recursive mode)\n"
@@ -854,6 +855,8 @@ plus_option(char *option, isc_boolean_t is_batchfile,
                        break;
                case 'n': /* dnssec */  
                        FULLCHECK("dnssec");
+                       if (state && lookup->edns == -1)
+                               lookup->edns = 0;
                        lookup->dnssec = state;
                        break;
                case 'o': /* domain */  
@@ -869,6 +872,16 @@ plus_option(char *option, isc_boolean_t is_batchfile,
                        goto invalid_option;
                }
                break;
+       case 'e':
+               FULLCHECK("edns");
+               if (!state) {
+                       lookup->edns = -1;
+                       break;
+               }
+               if (value == NULL)
+                       goto need_value;
+               lookup->edns = (isc_int16_t) parse_uint(value, "edns", 255);
+               break;
        case 'f': /* fail */
                FULLCHECK("fail");
                lookup->servfail_stops = state;
index 6b727b98950c285572257f39feda0f6fabe0aa8b..49aa1d1da3e89929dd1317612a784950e827dae0 100644 (file)
@@ -18,7 +18,7 @@
  - PERFORMANCE OF THIS SOFTWARE.
 -->
 
-<!-- $Id: dig.docbook,v 1.22 2005/05/13 01:35:38 marka Exp $ -->
+<!-- $Id: dig.docbook,v 1.23 2005/06/07 00:15:58 marka Exp $ -->
 <refentry>
 
   <refentryinfo>
           <listitem>
             <para>
               Set the UDP message buffer size advertised using EDNS0 to
-              <parameter>B</parameter> bytes.  The maximum and
-              minimum sizes of this
-              buffer are 65535 and 0 respectively.  Values outside this range
-              are
-              rounded up or down appropriately.
+              <parameter>B</parameter> bytes.  The maximum and minimum sizes
+             of this buffer are 65535 and 0 respectively.  Values outside
+             this range are rounded up or down appropriately.  
+             Values other than zero will cause a EDNS query to be sent.
             </para>
           </listitem>
         </varlistentry>
 
+       <varlistentry>
+         <term><option>+edns=#</option></term>
+         <listitem>
+           <para>
+              Specify the EDNS version to query with.  Valid values
+              are 0 to 255.  Setting the EDNS version will cause a
+              EDNS query to be sent.  <option>+noedns</option> clears the
+              remembered EDNS version.
+           </para>
+         </listitem>
+       </varlistentry>
+
         <varlistentry>
           <term><option>+[no]multiline</option></term>
           <listitem>
index 93b3c208703735d8fc6d5d1d24a49f43f3f1bfaa..fe7df5731f72298d50d7b5672693866b41b0cb63 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: dighost.c,v 1.276 2005/06/01 01:56:49 marka Exp $ */
+/* $Id: dighost.c,v 1.277 2005/06/07 00:15:58 marka Exp $ */
 
 /*! \file
  *  \note
@@ -702,6 +702,7 @@ make_empty_lookup(void) {
 #endif
 #endif
        looknew->udpsize = 0;
+       looknew->edns = -1;
        looknew->recurse = ISC_TRUE;
        looknew->aaonly = ISC_FALSE;
        looknew->adflag = ISC_FALSE;
@@ -778,6 +779,7 @@ clone_lookup(dig_lookup_t *lookold, isc_boolean_t servers) {
 #endif
 #endif
        looknew->udpsize = lookold->udpsize;
+       looknew->edns = lookold->edns;
        looknew->recurse = lookold->recurse;
        looknew->aaonly = lookold->aaonly;
        looknew->adflag = lookold->adflag;
@@ -1085,7 +1087,9 @@ setup_libs(void) {
  * options are UDP buffer size and the DO bit.
  */
 static void
-add_opt(dns_message_t *msg, isc_uint16_t udpsize, isc_boolean_t dnssec) {
+add_opt(dns_message_t *msg, isc_uint16_t udpsize, isc_uint16_t edns,
+       isc_boolean_t dnssec)
+{
        dns_rdataset_t *rdataset = NULL;
        dns_rdatalist_t *rdatalist = NULL;
        dns_rdata_t *rdata = NULL;
@@ -1104,9 +1108,9 @@ add_opt(dns_message_t *msg, isc_uint16_t udpsize, isc_boolean_t dnssec) {
        rdatalist->type = dns_rdatatype_opt;
        rdatalist->covers = 0;
        rdatalist->rdclass = udpsize;
-       rdatalist->ttl = 0;
+       rdatalist->ttl = edns << 16;
        if (dnssec)
-               rdatalist->ttl = DNS_MESSAGEEXTFLAG_DO;
+               rdatalist->ttl |= DNS_MESSAGEEXTFLAG_DO;
        rdata->data = NULL;
        rdata->length = 0;
        ISC_LIST_INIT(rdatalist->rdata);
@@ -1829,10 +1833,13 @@ setup_lookup(dig_lookup_t *lookup) {
        result = dns_message_renderbegin(lookup->sendmsg, &cctx,
                                         &lookup->sendbuf);
        check_result(result, "dns_message_renderbegin");
-       if (lookup->udpsize > 0 || lookup->dnssec) {
+       if (lookup->udpsize > 0 || lookup->dnssec || lookup->edns > -1) {
                if (lookup->udpsize == 0)
                        lookup->udpsize = 2048;
-               add_opt(lookup->sendmsg, lookup->udpsize, lookup->dnssec);
+               if (lookup->edns < 0)
+                       lookup->edns = 0;
+               add_opt(lookup->sendmsg, lookup->udpsize,
+                       lookup->edns, lookup->dnssec);
        }
 
        result = dns_message_rendersection(lookup->sendmsg,
index c59636a0abb356ab1d09b0c9ab70d3a5037eac4f..4028ff73c5f88f4069a87f21c00536dbf1a2f63a 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: dig.h,v 1.91 2005/04/27 04:55:45 sra Exp $ */
+/* $Id: dig.h,v 1.92 2005/06/07 00:15:59 marka Exp $ */
 
 #ifndef DIG_H
 #define DIG_H
@@ -180,6 +180,7 @@ isc_boolean_t       sigchase;
        isc_uint32_t retries;
        int nsfound;
        isc_uint16_t udpsize;
+       isc_int16_t edns;
        isc_uint32_t ixfr_serial;
        isc_buffer_t rdatabuf;
        char rdatastore[MXNAME];
index 067e32749718745ada474771bb5aef82292ec8ce..14009bf296776ec564764fc374dcbfb11e56b1a2 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: client.c,v 1.227 2005/06/04 05:32:46 jinmei Exp $ */
+/* $Id: client.c,v 1.228 2005/06/07 00:15:59 marka Exp $ */
 
 #include <config.h>
 
@@ -574,6 +574,7 @@ ns_client_endrequest(ns_client_t *client) {
 
        client->udpsize = 512;
        client->extflags = 0;
+       client->ednsversion = -1;
        dns_message_reset(client->message, DNS_MESSAGE_INTENTPARSE);
 
        if (client->recursionquota != NULL)
@@ -1363,8 +1364,6 @@ client_request(isc_task_t *task, isc_event_t *event) {
         */
        opt = dns_message_getopt(client->message);
        if (opt != NULL) {
-               unsigned int version;
-
                /*
                 * Set the client's UDP buffer size.
                 */
@@ -1383,22 +1382,24 @@ client_request(isc_task_t *task, isc_event_t *event) {
                client->extflags = (isc_uint16_t)(opt->ttl & 0xFFFF);
 
                /*
-                * Create an OPT for our reply.
+                * Do we understand this version of EDNS?
+                *
+                * XXXRTH need library support for this!
                 */
-               result = client_addopt(client);
-               if (result != ISC_R_SUCCESS) {
+               client->ednsversion = (opt->ttl & 0x00FF0000) >> 16;
+               if (client->ednsversion > 0) {
+                       result = client_addopt(client);
+                       if (result == ISC_R_SUCCESS)
+                               result = DNS_R_BADVERS;
                        ns_client_error(client, result);
                        goto cleanup;
                }
-
                /*
-                * Do we understand this version of ENDS?
-                *
-                * XXXRTH need library support for this!
+                * Create an OPT for our reply.
                 */
-               version = (opt->ttl & 0x00FF0000) >> 16;
-               if (version != 0) {
-                       ns_client_error(client, DNS_R_BADVERS);
+               result = client_addopt(client);
+               if (result != ISC_R_SUCCESS) {
+                       ns_client_error(client, result);
                        goto cleanup;
                }
        }
@@ -1776,6 +1777,7 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) {
        client->opt = NULL;
        client->udpsize = 512;
        client->extflags = 0;
+       client->ednsversion = -1;
        client->next = NULL;
        client->shutdown = NULL;
        client->shutdown_arg = NULL;
index 7993fc99de0a87e28e95a5d010cc53f6f5681d7b..6cec4d63cdcd7890d35f8daf10d94242ed794dfb 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: client.h,v 1.73 2005/04/27 04:55:56 sra Exp $ */
+/* $Id: client.h,v 1.74 2005/06/07 00:16:00 marka Exp $ */
 
 #ifndef NAMED_CLIENT_H
 #define NAMED_CLIENT_H 1
@@ -116,6 +116,7 @@ struct ns_client {
        dns_rdataset_t *        opt;
        isc_uint16_t            udpsize;
        isc_uint16_t            extflags;
+       isc_int16_t             ednsversion;    /* -1 noedns */
        void                    (*next)(ns_client_t *);
        void                    (*shutdown)(void *arg, isc_result_t result);
        void                    *shutdown_arg;
index 6f42c7bae08ba9a1feab842cd82b5d41d09482b3..a6555b601b0e37e7ba5784981543250d6345d9cf 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: resolver.h,v 1.44 2005/04/27 04:56:59 sra Exp $ */
+/* $Id: resolver.h,v 1.45 2005/06/07 00:16:01 marka Exp $ */
 
 #ifndef DNS_RESOLVER_H
 #define DNS_RESOLVER_H 1
@@ -91,6 +91,10 @@ typedef struct dns_fetchevent {
 #define DNS_FETCHOPT_FORWARDONLY       0x10         /*%< Only use forwarders. */
 #define DNS_FETCHOPT_NOVALIDATE                0x20         /*%< Disable validation. */
 
+#define        DNS_FETCHOPT_EDNSVERSIONSET     0x00800000
+#define        DNS_FETCHOPT_EDNSVERSIONMASK    0xff000000
+#define        DNS_FETCHOPT_EDNSVERSIONSHIFT   24
+
 /*
  * XXXRTH  Should this API be made semi-private?  (I.e.
  * _dns_resolver_create()).
index 012b67e7889256de2febb98e4edf715816ea23cc..f03b5dd283a0ccf7fa89553d4c8c555d3b179598 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: resolver.c,v 1.308 2005/06/04 05:32:47 jinmei Exp $ */
+/* $Id: resolver.c,v 1.309 2005/06/07 00:16:00 marka Exp $ */
 
 /*! \file */
 
@@ -841,7 +841,7 @@ resquery_senddone(isc_task_t *task, isc_event_t *event) {
 }
 
 static inline isc_result_t
-fctx_addopt(dns_message_t *message, dns_resolver_t *res) {
+fctx_addopt(dns_message_t *message, unsigned int version, dns_resolver_t *res) {
        dns_rdataset_t *rdataset;
        dns_rdatalist_t *rdatalist;
        dns_rdata_t *rdata;
@@ -870,9 +870,10 @@ fctx_addopt(dns_message_t *message, dns_resolver_t *res) {
        rdatalist->rdclass = res->udpsize;
 
        /*
-        * Set EXTENDED-RCODE, VERSION, and Z to 0, and the DO bit to 1.
+        * Set EXTENDED-RCODE and Z to 0, DO to 1.
         */
-       rdatalist->ttl = DNS_MESSAGEEXTFLAG_DO;
+       rdatalist->ttl = (version << 16);
+       rdatalist->ttl |= DNS_MESSAGEEXTFLAG_DO;
 
        /*
         * No EDNS options.
@@ -1233,7 +1234,14 @@ resquery_send(resquery_t *query) {
 
        if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
                if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) == 0) {
-                       result = fctx_addopt(fctx->qmessage, res);
+                       unsigned int version = 0;       /* Default version. */
+                       unsigned int flags;
+                       flags = query->addrinfo->flags;
+                       if ((flags & DNS_FETCHOPT_EDNSVERSIONSET) != 0) {
+                               version = flags & DNS_FETCHOPT_EDNSVERSIONMASK;
+                               version >>= DNS_FETCHOPT_EDNSVERSIONSHIFT;
+                       }
+                       result = fctx_addopt(fctx->qmessage, version, res);
                        if (result != ISC_R_SUCCESS) {
                                /*
                                 * We couldn't add the OPT, but we'll press on.
@@ -5277,6 +5285,28 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
                         * for this fetch.
                         */
                        result = DNS_R_YXDOMAIN;
+               } else if (message->rcode == dns_rcode_badvers) {
+                       dns_rdataset_t *opt;
+                       unsigned int flags, mask;
+                       unsigned int version;
+
+                       resend = ISC_TRUE;
+                       opt = dns_message_getopt(message);
+                       version = (opt->ttl >> 16) & 0xff;
+                       flags = (version << DNS_FETCHOPT_EDNSVERSIONSHIFT) |
+                               DNS_FETCHOPT_EDNSVERSIONSET;
+                       mask = DNS_FETCHOPT_EDNSVERSIONMASK |
+                              DNS_FETCHOPT_EDNSVERSIONSET;
+                       switch (version) {
+                       case 0:
+                               dns_adb_changeflags(fctx->adb, query->addrinfo,
+                                                   flags, mask);
+                               break;
+                       default:
+                               broken_server = DNS_R_BADVERS;
+                               keep_trying = ISC_TRUE;
+                               break;
+                       }
                } else {
                        /*
                         * XXXRTH log.