]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Recognise EDNS Client Tag and EDNS Server Tag
authorMark Andrews <marka@isc.org>
Wed, 27 Mar 2019 06:16:57 +0000 (17:16 +1100)
committerMark Andrews <marka@isc.org>
Thu, 9 May 2019 07:29:23 +0000 (17:29 +1000)
CHANGES
bin/dig/dighost.c
bin/tests/system/digdelv/tests.sh
lib/dns/include/dns/message.h
lib/dns/message.c
lib/dns/rdata/generic/opt_41.c

diff --git a/CHANGES b/CHANGES
index 587bd10c726ad457216cd2a13eadf524caa020b7..64239e7bd1673bef4f13084a3eccdb6dae4f18d1 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+5231.  [protocol]      Add support for displaying CLIENT-TAG and SERVER-TAG.
+                       [GL #960]
+
 5230.  [protocol]      The SHA-1 hash algorithm is no longer used when
                        generating DS and CDS records. [GL #1015]
 
index 3e7cef312083297af5bdbf0348f365bc7cf3ed01..a7ea34267031b32b7233dd4bd39f424dcb6c2242 100644 (file)
@@ -1411,6 +1411,8 @@ dig_ednsoptname_t optnames[] = {
        { 12, "PAD" },          /* shorthand */
        { 13, "CHAIN" },        /* RFC 7901 */
        { 14, "KEY-TAG" },      /* RFC 8145 */
+       { 16, "CLIENT-TAG" },   /* draft-bellis-dnsop-edns-tags */
+       { 17, "SERVER-TAG" },   /* draft-bellis-dnsop-edns-tags */
        { 26946, "DEVICEID" },  /* Brian Hartvigsen */
 };
 
index 22f074940b3a735234062c942c897a966c9dac4c..ba476288abd419e300918e84525593a6eda0f828 100644 (file)
@@ -548,6 +548,54 @@ if [ -x "$DIG" ] ; then
   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   status=$((status+ret))
 
+  n=$((n+1))
+  echo_i "check that dig processes +ednsopt=client-tag:value ($n)"
+  dig_with_opts @10.53.0.3 +ednsopt=client-tag:0001 a.example +qr > dig.out.test$n 2>&1 || ret=1
+  grep "; CLIENT-TAG: 1$" dig.out.test$n > /dev/null || ret=1
+  grep "status: FORMERR" dig.out.test$n > /dev/null && ret=1
+  if [ $ret -ne 0 ]; then echo_i "failed"; fi
+  status=$((status+ret))
+
+  n=$((n+1))
+  echo_i "check that FORMERR is returned for a too short client-tag ($n)"
+  dig_with_opts @10.53.0.3 +ednsopt=client-tag:01 a.example +qr > dig.out.test$n 2>&1 || ret=1
+  grep "; CLIENT-TAG" dig.out.test$n > /dev/null || ret=1
+  grep "status: FORMERR" dig.out.test$n > /dev/null || ret=1
+  if [ $ret -ne 0 ]; then echo_i "failed"; fi
+  status=$((status+ret))
+
+  n=$((n+1))
+  echo_i "check that FORMERR is returned for a too long client-tag ($n)"
+  dig_with_opts @10.53.0.3 +ednsopt=client-tag:000001 a.example +qr > dig.out.test$n 2>&1 || ret=1
+  grep "; CLIENT-TAG" dig.out.test$n > /dev/null || ret=1
+  grep "status: FORMERR" dig.out.test$n > /dev/null || ret=1
+  if [ $ret -ne 0 ]; then echo_i "failed"; fi
+  status=$((status+ret))
+
+  n=$((n+1))
+  echo_i "check that dig processes +ednsopt=server-tag:value ($n)"
+  dig_with_opts @10.53.0.3 +ednsopt=server-tag:0001 a.example +qr > dig.out.test$n 2>&1 || ret=1
+  grep "; SERVER-TAG: 1$" dig.out.test$n > /dev/null || ret=1
+  grep "status: FORMERR" dig.out.test$n > /dev/null && ret=1
+  if [ $ret -ne 0 ]; then echo_i "failed"; fi
+  status=$((status+ret))
+
+  n=$((n+1))
+  echo_i "check that FORMERR is returned for a too short server-tag ($n)"
+  dig_with_opts @10.53.0.3 +ednsopt=server-tag:01 a.example +qr > dig.out.test$n 2>&1 || ret=1
+  grep "; SERVER-TAG" dig.out.test$n > /dev/null || ret=1
+  grep "status: FORMERR" dig.out.test$n > /dev/null || ret=1
+  if [ $ret -ne 0 ]; then echo_i "failed"; fi
+  status=$((status+ret))
+
+  n=$((n+1))
+  echo_i "check that FORMERR is returned for a too long server-tag ($n)"
+  dig_with_opts @10.53.0.3 +ednsopt=server-tag:000001 a.example +qr > dig.out.test$n 2>&1 || ret=1
+  grep "; SERVER-TAG" dig.out.test$n > /dev/null || ret=1
+  grep "status: FORMERR" dig.out.test$n > /dev/null || ret=1
+  if [ $ret -ne 0 ]; then echo_i "failed"; fi
+  status=$((status+ret))
+
   n=$((n+1))
   echo_i "check that dig handles malformed option '+ednsopt=:' gracefully ($n)"
   ret=0
index b933a57c91cbd66841ebdd7835f860c571b1f834..1f793b4809972f1239d64942ea01a1e7e4dec43f 100644 (file)
 #define DNS_OPT_TCP_KEEPALIVE  11              /*%< TCP keepalive opt code */
 #define DNS_OPT_PAD            12              /*%< PAD opt code */
 #define DNS_OPT_KEY_TAG                14              /*%< Key tag opt code */
+#define DNS_OPT_CLIENT_TAG     16              /*%< Client tag opt code */
+#define DNS_OPT_SERVER_TAG     17              /*%< Server tag opt code */
 
 /*%< Experimental options [65001...65534] as per RFC6891 */
 
index 8a12c1f1cb3b69a89e1994174d4b77eaad9d8f66..23be406838c311665c1363227cb7b8e6812f5b11 100644 (file)
@@ -3582,6 +3582,30 @@ dns_message_pseudosectiontoyaml(dns_message_t *msg,
                                        ADD_STRING(target, "\n");
                                        continue;
                                }
+                       } else if (optcode == DNS_OPT_CLIENT_TAG) {
+                               uint16_t id;
+                               INDENT(style);
+                               ADD_STRING(target, "CLIENT-TAG");
+                               if (optlen == 2U) {
+                                       id = isc_buffer_getuint16(&optbuf);
+                                       snprintf(buf, sizeof(buf), ": %u\n",
+                                                id);
+                                       ADD_STRING(target, buf);
+                                       optlen -= 2;
+                                       continue;
+                               }
+                       } else if (optcode == DNS_OPT_SERVER_TAG) {
+                               uint16_t id;
+                               INDENT(style);
+                               ADD_STRING(target, "SERVER-TAG");
+                               if (optlen == 2U) {
+                                       id = isc_buffer_getuint16(&optbuf);
+                                       snprintf(buf, sizeof(buf), ": %u\n",
+                                                id);
+                                       ADD_STRING(target, buf);
+                                       optlen -= 2;
+                                       continue;
+                               }
                        } else {
                                INDENT(style);
                                ADD_STRING(target, "OPT: ");
@@ -3851,6 +3875,28 @@ dns_message_pseudosectiontotext(dns_message_t *msg,
                                        ADD_STRING(target, "\n");
                                        continue;
                                }
+                       } else if (optcode == DNS_OPT_CLIENT_TAG) {
+                               uint16_t id;
+                               ADD_STRING(target, "; CLIENT-TAG");
+                               if (optlen == 2U) {
+                                       id = isc_buffer_getuint16(&optbuf);
+                                       snprintf(buf, sizeof(buf), ": %u\n",
+                                                id);
+                                       ADD_STRING(target, buf);
+                                       optlen -= 2;
+                                       continue;
+                               }
+                       } else if (optcode == DNS_OPT_SERVER_TAG) {
+                               uint16_t id;
+                               ADD_STRING(target, "; SERVER-TAG");
+                               if (optlen == 2U) {
+                                       id = isc_buffer_getuint16(&optbuf);
+                                       snprintf(buf, sizeof(buf), ": %u\n",
+                                                id);
+                                       ADD_STRING(target, buf);
+                                       optlen -= 2;
+                                       continue;
+                               }
                        } else {
                                ADD_STRING(target, "; OPT=");
                                snprintf(buf, sizeof(buf), "%u", optcode);
index b102cf2f42c14b6966aac9df4a8618571eef226e..b8b7f53656ba3a36d026549769e4afb46c8818f1 100644 (file)
@@ -99,19 +99,22 @@ fromwire_opt(ARGS_FROMWIRE) {
        UNUSED(options);
 
        isc_buffer_activeregion(source, &sregion);
-       if (sregion.length == 0)
+       if (sregion.length == 0) {
                return (ISC_R_SUCCESS);
+       }
        total = 0;
        while (sregion.length != 0) {
-               if (sregion.length < 4)
+               if (sregion.length < 4) {
                        return (ISC_R_UNEXPECTEDEND);
+               }
                opt = uint16_fromregion(&sregion);
                isc_region_consume(&sregion, 2);
                length = uint16_fromregion(&sregion);
                isc_region_consume(&sregion, 2);
                total += 4;
-               if (sregion.length < length)
+               if (sregion.length < length) {
                        return (ISC_R_UNEXPECTEDEND);
+               }
                switch (opt) {
                case DNS_OPT_CLIENT_SUBNET: {
                        uint16_t family;
@@ -119,8 +122,9 @@ fromwire_opt(ARGS_FROMWIRE) {
                        uint8_t scope;
                        uint8_t addrbytes;
 
-                       if (length < 4)
+                       if (length < 4) {
                                return (DNS_R_OPTERR);
+                       }
                        family = uint16_fromregion(&sregion);
                        isc_region_consume(&sregion, 2);
                        addrlen = uint8_fromregion(&sregion);
@@ -139,29 +143,34 @@ fromwire_opt(ARGS_FROMWIRE) {
                                 * lengths don't make sense because the
                                 * family is unknown.
                                 */
-                               if (addrlen != 0U || scope != 0U)
+                               if (addrlen != 0U || scope != 0U) {
                                        return (DNS_R_OPTERR);
+                               }
                                break;
                        case 1:
-                               if (addrlen > 32U || scope > 32U)
+                               if (addrlen > 32U || scope > 32U) {
                                        return (DNS_R_OPTERR);
+                               }
                                break;
                        case 2:
-                               if (addrlen > 128U || scope > 128U)
+                               if (addrlen > 128U || scope > 128U) {
                                        return (DNS_R_OPTERR);
+                               }
                                break;
                        default:
                                return (DNS_R_OPTERR);
                        }
                        addrbytes = (addrlen + 7) / 8;
-                       if (addrbytes + 4 != length)
+                       if (addrbytes + 4 != length) {
                                return (DNS_R_OPTERR);
+                       }
 
                        if (addrbytes != 0U && (addrlen % 8) != 0) {
                                uint8_t bits = ~0U << (8 - (addrlen % 8));
                                bits &= sregion.base[addrbytes - 1];
-                               if (bits != sregion.base[addrbytes - 1])
+                               if (bits != sregion.base[addrbytes - 1]) {
                                        return (DNS_R_OPTERR);
+                               }
                        }
                        isc_region_consume(&sregion, addrbytes);
                        break;
@@ -170,18 +179,29 @@ fromwire_opt(ARGS_FROMWIRE) {
                        /*
                         * Request has zero length.  Response is 32 bits.
                         */
-                       if (length != 0 && length != 4)
+                       if (length != 0 && length != 4) {
                                return (DNS_R_OPTERR);
+                       }
                        isc_region_consume(&sregion, length);
                        break;
                case DNS_OPT_COOKIE:
-                       if (length != 8 && (length < 16 || length > 40))
+                       if (length != 8 && (length < 16 || length > 40)) {
                                return (DNS_R_OPTERR);
+                       }
                        isc_region_consume(&sregion, length);
                        break;
                case DNS_OPT_KEY_TAG:
-                       if (length == 0 || (length % 2) != 0)
+                       if (length == 0 || (length % 2) != 0) {
                                return (DNS_R_OPTERR);
+                       }
+                       isc_region_consume(&sregion, length);
+                       break;
+               case DNS_OPT_CLIENT_TAG:
+                       /* FALLTHROUGH */
+               case DNS_OPT_SERVER_TAG:
+                       if (length != 2) {
+                               return (DNS_R_OPTERR);
+                       }
                        isc_region_consume(&sregion, length);
                        break;
                default:
@@ -193,8 +213,9 @@ fromwire_opt(ARGS_FROMWIRE) {
 
        isc_buffer_activeregion(source, &sregion);
        isc_buffer_availableregion(target, &tregion);
-       if (tregion.length < total)
+       if (tregion.length < total) {
                return (ISC_R_NOSPACE);
+       }
        memmove(tregion.base, sregion.base, total);
        isc_buffer_forward(source, total);
        isc_buffer_add(target, total);