]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Check walking the hip rendezvous servers.
authorMark Andrews <marka@isc.org>
Wed, 22 Jul 2020 07:02:47 +0000 (17:02 +1000)
committerMark Andrews <marka@isc.org>
Fri, 24 Jul 2020 04:15:56 +0000 (04:15 +0000)
Also fixes extraneous white space at end of record when
there are no rendezvous servers.

bin/tests/system/xfer/dig1.good
bin/tests/system/xfer/dig2.good
lib/dns/rdata/generic/hip_55.c
lib/dns/tests/rdata_test.c

index dde3a55ec70500cac65c2f2babf5c257af22b067..e813b718893952a94efa53d901082cef568a8053 100644 (file)
@@ -57,7 +57,7 @@ gpos01.example.               3600    IN      GPOS    "-22.6882" "116.8652" "250.0"
 gpos02.example.                3600    IN      GPOS    "" "" ""
 hinfo01.example.       3600    IN      HINFO   "Generic PC clone" "NetBSD-1.4"
 hinfo02.example.       3600    IN      HINFO   "PC" "NetBSD"
-hip1.example.          3600    IN      HIP     2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D 
+hip1.example.          3600    IN      HIP     2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D
 hip2.example.          3600    IN      HIP     2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs.example.com.
 ipseckey01.example.    3600    IN      IPSECKEY  10 1 2 192.0.2.38 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
 ipseckey02.example.    3600    IN      IPSECKEY  10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
index 106d03a07ba4cfb32b646f740de36d1339391166..f6c22d418de6d502a1efb40a7906eaf50e5c011d 100644 (file)
@@ -66,7 +66,7 @@ isdn01.example.               3600    IN      ISDN    "isdn-address"
 isdn02.example.                3600    IN      ISDN    "isdn-address" "subaddress"
 isdn03.example.                3600    IN      ISDN    "isdn-address"
 isdn04.example.                3600    IN      ISDN    "isdn-address" "subaddress"
-hip1.example.          3600    IN      HIP     2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D 
+hip1.example.          3600    IN      HIP     2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D
 hip2.example.          3600    IN      HIP     2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs.example.com.
 dnskey01.example.      3600    IN      DNSKEY  512 255 1 AQMFD5raczCJHViKtLYhWGz8hMY9UGRuniJDBzC7w0aRyzWZriO6i2od GWWQVucZqKVsENW91IOW4vqudngPZsY3GvQ/xVA8/7pyFj6b7Esga60z yGW6LFe9r8n6paHrlG5ojqf0BaqHT+8=
 keydata.example.       3600    IN      TYPE65533 \# 0
index c114c0c915e56b52fe4a75b1f8a0b630272728ff..83e64c93360113b822bd965e14a50bfb2db65612 100644 (file)
@@ -165,7 +165,9 @@ totext_hip(ARGS_TOTEXT) {
        region.length = key_len;
        RETERR(isc_base64_totext(&region, 1, "", target));
        region.length = length - key_len;
-       RETERR(str_totext(tctx->linebreak, target));
+       if (region.length > 0) {
+               RETERR(str_totext(tctx->linebreak, target));
+       }
 
        /*
         * Rendezvous Servers.
@@ -441,7 +443,7 @@ dns_rdata_hip_next(dns_rdata_hip_t *hip) {
        dns_name_fromregion(&name, &region);
        hip->offset += name.length;
        INSIST(hip->offset <= hip->servers_len);
-       return (ISC_R_SUCCESS);
+       return (hip->offset < hip->servers_len ? ISC_R_SUCCESS : ISC_R_NOMORE);
 }
 
 void
index 96f419b6b9480b7445705c98d2cb101cccb0b32d..41529c6610491498f5955d290bf2178864f64b77 100644 (file)
@@ -75,6 +75,7 @@ typedef struct text_ok {
        const char *text_in;  /* text passed to fromtext_*() */
        const char *text_out; /* text expected from totext_*();
                               * NULL indicates text_in is invalid */
+       unsigned int loop;
 } text_ok_t;
 
 /*
@@ -84,6 +85,7 @@ typedef struct wire_ok {
        unsigned char data[512]; /* RDATA in wire format */
        size_t len;              /* octets of data to parse */
        bool ok;                 /* is this RDATA valid? */
+       unsigned int loop;
 } wire_ok_t;
 
 #define COMPARE(r1, r2, answer)          \
@@ -97,32 +99,41 @@ typedef struct wire_ok {
 
 #define TEXT_VALID_CHANGED(data_in, data_out) \
        {                                     \
-               data_in, data_out             \
+               data_in, data_out, 0          \
        }
-#define TEXT_VALID(data)   \
-       {                  \
-               data, data \
+#define TEXT_VALID(data)      \
+       {                     \
+               data, data, 0 \
        }
-#define TEXT_INVALID(data) \
-       {                  \
-               data, NULL \
+#define TEXT_VALID_LOOP(loop, data) \
+       {                           \
+               data, data, loop    \
+       }
+#define TEXT_VALID_LOOPCHG(loop, data_in, data_out) \
+       {                                           \
+               data_in, data_out, loop             \
+       }
+#define TEXT_INVALID(data)    \
+       {                     \
+               data, NULL, 0 \
        }
 #define TEXT_SENTINEL() TEXT_INVALID(NULL)
 
 #define VARGC(...) (sizeof((unsigned char[]){ __VA_ARGS__ }))
-#define WIRE_TEST(ok, ...)                              \
-       {                                               \
-               { __VA_ARGS__ }, VARGC(__VA_ARGS__), ok \
+#define WIRE_TEST(ok, loop, ...)                              \
+       {                                                     \
+               { __VA_ARGS__ }, VARGC(__VA_ARGS__), ok, loop \
        }
-#define WIRE_VALID(...) WIRE_TEST(true, __VA_ARGS__)
+#define WIRE_VALID(...)                   WIRE_TEST(true, 0, __VA_ARGS__)
+#define WIRE_VALID_LOOP(loop, ...) WIRE_TEST(true, loop, __VA_ARGS__)
 /*
  * WIRE_INVALID() test cases must always have at least one octet specified to
  * distinguish them from WIRE_SENTINEL().  Use the 'empty_ok' parameter passed
  * to check_wire_ok() for indicating whether empty RDATA is allowed for a given
  * RR type or not.
  */
-#define WIRE_INVALID(FIRST, ...) WIRE_TEST(false, FIRST, __VA_ARGS__)
-#define WIRE_SENTINEL()                 WIRE_TEST(false)
+#define WIRE_INVALID(FIRST, ...) WIRE_TEST(false, 0, FIRST, __VA_ARGS__)
+#define WIRE_SENTINEL()                 WIRE_TEST(false, 0)
 
 /*
  * Call dns_rdata_fromwire() for data in 'src', which is 'srclen' octets in
@@ -252,13 +263,15 @@ rdata_checknames(dns_rdata_t *rdata) {
  * check_text_ok_single() and check_wire_ok_single().
  */
 static void
-check_struct_conversions(dns_rdata_t *rdata, size_t structsize) {
+check_struct_conversions(dns_rdata_t *rdata, size_t structsize,
+                        unsigned int loop) {
        dns_rdataclass_t rdclass = rdata->rdclass;
        dns_rdatatype_t type = rdata->type;
        isc_result_t result;
        isc_buffer_t target;
        void *rdata_struct;
        char buf[1024];
+       unsigned int count = 0;
 
        rdata_struct = isc_mem_allocate(dt_mctx, structsize);
        assert_non_null(rdata_struct);
@@ -284,6 +297,29 @@ check_struct_conversions(dns_rdata_t *rdata, size_t structsize) {
 
        assert_memory_equal(buf, rdata->data, rdata->length);
 
+       /*
+        * Check that one can walk hip rendezvous servers.
+        */
+       switch (type) {
+       case dns_rdatatype_hip: {
+               dns_rdata_hip_t *hip = rdata_struct;
+
+               for (result = dns_rdata_hip_first(hip); result == ISC_R_SUCCESS;
+                    result = dns_rdata_hip_next(hip))
+               {
+                       dns_name_t name;
+                       dns_name_init(&name, NULL);
+                       dns_rdata_hip_current(hip, &name);
+                       assert_int_not_equal(dns_name_countlabels(&name), 0);
+                       assert_true(dns_name_isabsolute(&name));
+                       count++;
+               }
+               assert_int_equal(result, ISC_R_NOMORE);
+               assert_int_equal(count, loop);
+               break;
+       }
+       }
+
        isc_mem_free(dt_mctx, rdata_struct);
 }
 
@@ -382,7 +418,7 @@ check_text_ok_single(const text_ok_t *text_ok, dns_rdataclass_t rdclass,
         * Perform two-way conversion checks between uncompressed wire form and
         * type-specific struct.
         */
-       check_struct_conversions(&rdata, structsize);
+       check_struct_conversions(&rdata, structsize, text_ok->loop);
 }
 
 /*
@@ -521,7 +557,7 @@ check_wire_ok_single(const wire_ok_t *wire_ok, dns_rdataclass_t rdclass,
         *   - uncompressed wire form and text form,
         *   - uncompressed wire form and multi-line text form.
         */
-       check_struct_conversions(&rdata, structsize);
+       check_struct_conversions(&rdata, structsize, wire_ok->loop);
        if (!dns_rdatatype_ismeta(rdata.type)) {
                check_text_conversions(&rdata);
                check_multiline_text_conversions(&rdata);
@@ -576,7 +612,7 @@ check_text_ok(const text_ok_t *text_ok, dns_rdataclass_t rdclass,
 static void
 check_wire_ok(const wire_ok_t *wire_ok, bool empty_ok, dns_rdataclass_t rdclass,
              dns_rdatatype_t type, size_t structsize) {
-       wire_ok_t empty_wire = WIRE_TEST(empty_ok);
+       wire_ok_t empty_wire = WIRE_TEST(empty_ok, 0);
        size_t i;
 
        /*
@@ -1755,6 +1791,33 @@ eid(void **state) {
  */
 static void
 hip(void **state) {
+       text_ok_t text_ok[] = {
+               /* RFC 8005 examples. */
+               TEXT_VALID_LOOP(0, "2 200100107B1A74DF365639CC39F1D578 "
+                                  "AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cI"
+                                  "vM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbW"
+                                  "Iy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+b"
+                                  "SRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWx"
+                                  "Z48AWkskmdHaVDP4BcelrTI3rMXdXF5D"),
+               TEXT_VALID_LOOP(1, "2 200100107B1A74DF365639CC39F1D578 "
+                                  "AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cI"
+                                  "vM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbW"
+                                  "Iy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+b"
+                                  "SRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWx"
+                                  "Z48AWkskmdHaVDP4BcelrTI3rMXdXF5D "
+                                  "rvs1.example.com."),
+               TEXT_VALID_LOOP(2, "2 200100107B1A74DF365639CC39F1D578 "
+                                  "AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cI"
+                                  "vM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbW"
+                                  "Iy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+b"
+                                  "SRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWx"
+                                  "Z48AWkskmdHaVDP4BcelrTI3rMXdXF5D "
+                                  "rvs1.example.com. rvs2.example.com."),
+               /*
+                * Sentinel.
+                */
+               TEXT_SENTINEL()
+       };
        unsigned char hipwire[DNS_RDATA_MAXLENGTH] = { 0x01, 0x00, 0x00, 0x01,
                                                       0x00, 0x00, 0x04, 0x41,
                                                       0x42, 0x43, 0x44, 0x00 };
@@ -1776,6 +1839,8 @@ hip(void **state) {
        result = wire_to_rdata(hipwire, sizeof(hipwire), dns_rdataclass_in,
                               dns_rdatatype_hip, buf, sizeof(buf), &rdata);
        assert_int_equal(result, DNS_R_FORMERR);
+       check_text_ok(text_ok, dns_rdataclass_in, dns_rdatatype_hip,
+                     sizeof(dns_rdata_hip_t));
 }
 
 /*