Commit a14445d4 authored by Mark Andrews's avatar Mark Andrews

Merge branch '2043-dns_rdata_hip_next-fails-to-return-isc_r_nomore-at-the-right-time' into 'main'

Resolve "dns_rdata_hip_next() fails to return ISC_R_NOMORE at the right time."

Closes #2043

See merge request !3880
parents e31bcac4 bcd049f1
Pipeline #47422 passed with stages
in 2 minutes and 3 seconds
5474. [bug] dns_rdata_hip_next() failed to return ISC_R_NOMORE
when it should have. [GL !3880]
5473. [func] The rbt hashtable implementation has been changed 5473. [func] The rbt hashtable implementation has been changed
to use faster hash-function (HalfSipHash2-4) and to use faster hash-function (HalfSipHash2-4) and
uses Fibonacci hashing for better distribution. uses Fibonacci hashing for better distribution.
......
...@@ -57,7 +57,7 @@ gpos01.example. 3600 IN GPOS "-22.6882" "116.8652" "250.0" ...@@ -57,7 +57,7 @@ gpos01.example. 3600 IN GPOS "-22.6882" "116.8652" "250.0"
gpos02.example. 3600 IN GPOS "" "" "" gpos02.example. 3600 IN GPOS "" "" ""
hinfo01.example. 3600 IN HINFO "Generic PC clone" "NetBSD-1.4" hinfo01.example. 3600 IN HINFO "Generic PC clone" "NetBSD-1.4"
hinfo02.example. 3600 IN HINFO "PC" "NetBSD" 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. 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== ipseckey01.example. 3600 IN IPSECKEY 10 1 2 192.0.2.38 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
ipseckey02.example. 3600 IN IPSECKEY 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== ipseckey02.example. 3600 IN IPSECKEY 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
......
...@@ -66,7 +66,7 @@ isdn01.example. 3600 IN ISDN "isdn-address" ...@@ -66,7 +66,7 @@ isdn01.example. 3600 IN ISDN "isdn-address"
isdn02.example. 3600 IN ISDN "isdn-address" "subaddress" isdn02.example. 3600 IN ISDN "isdn-address" "subaddress"
isdn03.example. 3600 IN ISDN "isdn-address" isdn03.example. 3600 IN ISDN "isdn-address"
isdn04.example. 3600 IN ISDN "isdn-address" "subaddress" 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. 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= dnskey01.example. 3600 IN DNSKEY 512 255 1 AQMFD5raczCJHViKtLYhWGz8hMY9UGRuniJDBzC7w0aRyzWZriO6i2od GWWQVucZqKVsENW91IOW4vqudngPZsY3GvQ/xVA8/7pyFj6b7Esga60z yGW6LFe9r8n6paHrlG5ojqf0BaqHT+8=
keydata.example. 3600 IN TYPE65533 \# 0 keydata.example. 3600 IN TYPE65533 \# 0
......
...@@ -165,7 +165,9 @@ totext_hip(ARGS_TOTEXT) { ...@@ -165,7 +165,9 @@ totext_hip(ARGS_TOTEXT) {
region.length = key_len; region.length = key_len;
RETERR(isc_base64_totext(&region, 1, "", target)); RETERR(isc_base64_totext(&region, 1, "", target));
region.length = length - key_len; region.length = length - key_len;
RETERR(str_totext(tctx->linebreak, target)); if (region.length > 0) {
RETERR(str_totext(tctx->linebreak, target));
}
/* /*
* Rendezvous Servers. * Rendezvous Servers.
...@@ -441,7 +443,7 @@ dns_rdata_hip_next(dns_rdata_hip_t *hip) { ...@@ -441,7 +443,7 @@ dns_rdata_hip_next(dns_rdata_hip_t *hip) {
dns_name_fromregion(&name, &region); dns_name_fromregion(&name, &region);
hip->offset += name.length; hip->offset += name.length;
INSIST(hip->offset <= hip->servers_len); INSIST(hip->offset <= hip->servers_len);
return (ISC_R_SUCCESS); return (hip->offset < hip->servers_len ? ISC_R_SUCCESS : ISC_R_NOMORE);
} }
void void
......
...@@ -75,6 +75,7 @@ typedef struct text_ok { ...@@ -75,6 +75,7 @@ typedef struct text_ok {
const char *text_in; /* text passed to fromtext_*() */ const char *text_in; /* text passed to fromtext_*() */
const char *text_out; /* text expected from totext_*(); const char *text_out; /* text expected from totext_*();
* NULL indicates text_in is invalid */ * NULL indicates text_in is invalid */
unsigned int loop;
} text_ok_t; } text_ok_t;
/* /*
...@@ -84,6 +85,7 @@ typedef struct wire_ok { ...@@ -84,6 +85,7 @@ typedef struct wire_ok {
unsigned char data[512]; /* RDATA in wire format */ unsigned char data[512]; /* RDATA in wire format */
size_t len; /* octets of data to parse */ size_t len; /* octets of data to parse */
bool ok; /* is this RDATA valid? */ bool ok; /* is this RDATA valid? */
unsigned int loop;
} wire_ok_t; } wire_ok_t;
#define COMPARE(r1, r2, answer) \ #define COMPARE(r1, r2, answer) \
...@@ -97,32 +99,41 @@ typedef struct wire_ok { ...@@ -97,32 +99,41 @@ typedef struct wire_ok {
#define TEXT_VALID_CHANGED(data_in, data_out) \ #define TEXT_VALID_CHANGED(data_in, data_out) \
{ \ { \
data_in, data_out \ data_in, data_out, 0 \
} }
#define TEXT_VALID(data) \ #define TEXT_VALID(data) \
{ \ { \
data, data \ data, data, 0 \
} }
#define TEXT_INVALID(data) \ #define TEXT_VALID_LOOP(loop, data) \
{ \ { \
data, NULL \ 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 TEXT_SENTINEL() TEXT_INVALID(NULL)
#define VARGC(...) (sizeof((unsigned char[]){ __VA_ARGS__ })) #define VARGC(...) (sizeof((unsigned char[]){ __VA_ARGS__ }))
#define WIRE_TEST(ok, ...) \ #define WIRE_TEST(ok, loop, ...) \
{ \ { \
{ __VA_ARGS__ }, VARGC(__VA_ARGS__), ok \ { __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 * WIRE_INVALID() test cases must always have at least one octet specified to
* distinguish them from WIRE_SENTINEL(). Use the 'empty_ok' parameter passed * 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 * to check_wire_ok() for indicating whether empty RDATA is allowed for a given
* RR type or not. * RR type or not.
*/ */
#define WIRE_INVALID(FIRST, ...) WIRE_TEST(false, FIRST, __VA_ARGS__) #define WIRE_INVALID(FIRST, ...) WIRE_TEST(false, 0, FIRST, __VA_ARGS__)
#define WIRE_SENTINEL() WIRE_TEST(false) #define WIRE_SENTINEL() WIRE_TEST(false, 0)
/* /*
* Call dns_rdata_fromwire() for data in 'src', which is 'srclen' octets in * Call dns_rdata_fromwire() for data in 'src', which is 'srclen' octets in
...@@ -252,13 +263,15 @@ rdata_checknames(dns_rdata_t *rdata) { ...@@ -252,13 +263,15 @@ rdata_checknames(dns_rdata_t *rdata) {
* check_text_ok_single() and check_wire_ok_single(). * check_text_ok_single() and check_wire_ok_single().
*/ */
static void 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_rdataclass_t rdclass = rdata->rdclass;
dns_rdatatype_t type = rdata->type; dns_rdatatype_t type = rdata->type;
isc_result_t result; isc_result_t result;
isc_buffer_t target; isc_buffer_t target;
void *rdata_struct; void *rdata_struct;
char buf[1024]; char buf[1024];
unsigned int count = 0;
rdata_struct = isc_mem_allocate(dt_mctx, structsize); rdata_struct = isc_mem_allocate(dt_mctx, structsize);
assert_non_null(rdata_struct); assert_non_null(rdata_struct);
...@@ -284,6 +297,29 @@ check_struct_conversions(dns_rdata_t *rdata, size_t structsize) { ...@@ -284,6 +297,29 @@ check_struct_conversions(dns_rdata_t *rdata, size_t structsize) {
assert_memory_equal(buf, rdata->data, rdata->length); 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); 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, ...@@ -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 * Perform two-way conversion checks between uncompressed wire form and
* type-specific struct. * 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, ...@@ -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 text form,
* - uncompressed wire form and multi-line 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)) { if (!dns_rdatatype_ismeta(rdata.type)) {
check_text_conversions(&rdata); check_text_conversions(&rdata);
check_multiline_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, ...@@ -576,7 +612,7 @@ check_text_ok(const text_ok_t *text_ok, dns_rdataclass_t rdclass,
static void static void
check_wire_ok(const wire_ok_t *wire_ok, bool empty_ok, dns_rdataclass_t rdclass, check_wire_ok(const wire_ok_t *wire_ok, bool empty_ok, dns_rdataclass_t rdclass,
dns_rdatatype_t type, size_t structsize) { 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; size_t i;
/* /*
...@@ -1755,6 +1791,33 @@ eid(void **state) { ...@@ -1755,6 +1791,33 @@ eid(void **state) {
*/ */
static void static void
hip(void **state) { 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, unsigned char hipwire[DNS_RDATA_MAXLENGTH] = { 0x01, 0x00, 0x00, 0x01,
0x00, 0x00, 0x04, 0x41, 0x00, 0x00, 0x04, 0x41,
0x42, 0x43, 0x44, 0x00 }; 0x42, 0x43, 0x44, 0x00 };
...@@ -1776,6 +1839,8 @@ hip(void **state) { ...@@ -1776,6 +1839,8 @@ hip(void **state) {
result = wire_to_rdata(hipwire, sizeof(hipwire), dns_rdataclass_in, result = wire_to_rdata(hipwire, sizeof(hipwire), dns_rdataclass_in,
dns_rdatatype_hip, buf, sizeof(buf), &rdata); dns_rdatatype_hip, buf, sizeof(buf), &rdata);
assert_int_equal(result, DNS_R_FORMERR); assert_int_equal(result, DNS_R_FORMERR);
check_text_ok(text_ok, dns_rdataclass_in, dns_rdatatype_hip,
sizeof(dns_rdata_hip_t));
} }
/* /*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment