Chaosnet A records comparison bug
Summary
This is a bug in code I helped write in 2005, which got some finishing touches by marka@isc.org. It adds support for Chaosnet A records. It was filed as ISC-Bugs #14695 at the time. With the recently increased interest in Chaosnet, e.g for emulated systems, the code is used more than ever before and I would appreciate if the bug was fixed - I include a suggested patch towards the end. If you are not familiar with the format or how to make a working Chaosnet zone config, see the included sketches, have a look at https://its.victor.se/wiki/chaos-dns, or email me.
The bug:
- When a CH-class zone file specifies more than one CH-class A record for a host (e.g. a router), in the same address domain written in the same case, only the last one is used.
- If the first two bytes of the address domains are in different case, both are used, even if they have the same numeric address part and thus represent the same address.
Steps to reproduce
Create a CH-class zone file (see above) with a single host, with two A records, e.g.
bar.foo. A CH-ADDR.NET. 4242
A CH-ADDR.NET. 4711
Load the zone and examine the A record of foo with e.g.
host -t ch -t a bar.foo.
Observe that only one A record is listed.
Now change the zone file so the second A record is
A ch-ADDR.NET. 4711
Reload the zone, and examine the A record again. Note that both records are listed.
Further, change the second A record to
A CH-addr.NET. 4711
reload, observe that again only one record is listed.
Now, change the second A record to
A ch-ADDR.NET. 4242
reload, and observe two A records with the same meaning - one in the domain CH-ADDR.NET and one in ch-ADDR.NET.
What is the current bug behavior?
See above. The result is that as a workaround, Chaosnet zone files must use different case for (the first two bytes of the) address domains for hosts with multiple addresses, such as routers. Duplicated A records are not filtered when they represent the same address.
What is the expected correct behavior?
Regardless of the case, A records representing different addresses should be kept, while A records representing the same address should be filtered (only one copy should be kept).
Relevant configuration files
named.conf snippet (note you need to create a view for IN class data too, see https://its.victor.se/wiki/chaos-dns):
view "chaos" CH {
zone "foo" ch {
type master;
file "foo.zone";
};
};
file foo.zone
$ORIGIN foo.
$TTL 3600
; whatever works in your case
@ SOA isc.org. bugs.isc.org. (
2018092701 10800 3600 604800 3600)
NS isc.org.
; comment out lines as appropriate for testing
Bar A CH-ADDR.NET. 3412
A ch-ADDR.NET. 3412
A CH-ADDR.NET. 3413
Relevant logs and/or screenshots
Possible fixes
The bug is in lib/dns/rdata/ch_3/a_1.c line 177 (in the current version), see https://gitlab.isc.org/isc-projects/bind9/blob/master/lib/dns/rdata/ch_3/a_1.c#L177.
The function compare_ch_a
which compares two chaosnet A records is wrong, comparing the wrong parts of the data, resulting in the behaviour explained above.
The fix:
Change
order = memcmp(rdata1->data, rdata2->data, 2);
which compares the first two bytes of the address domains, to
order = memcmp(region1.base, region2.base, 2);
which compares the "next" two bytes of the record data (indexes were updated around line 171 using isc_region_consume). (If you want to be ultra-defensive, check the regionX.length, but I guess the rdata has already been validated.)
The bug is probably caused by cut-and-paste + reordering from generic/mx_15.c.