dnspython icon indicating copy to clipboard operation
dnspython copied to clipboard

Add support for more bases in `$GENERATE`

Open corubba opened this issue 3 years ago • 3 comments

When reading a zone from a zonefile, the $GENERATE resolution now not only supports decimal but also octal, hexadecimal and nibbles.

When using nibbles with an even width, the generated index may end with a dot, and alone is interpreted as a absolute name. This behaviour is consistent with bind, but may cause these records to be dropped by the subdomain-check in zonefile.py:398 (see also the h.* labels in the testcase that are missing from the expected result).

I also did a bit of refactoring to remove the duplicate code for calculating the index.

corubba avatar Aug 05 '22 12:08 corubba

Just a note that I haven't forgotten about this PR, but I haven't had time to properly review it yet. The weird absolute name thing you mention seems bad, even if it is compatible with BIND, but I don't remember "nibble mode" enough to have an informed opinion at the moment.

rthalley avatar Aug 09 '22 16:08 rthalley

No worries. Just to add a bit of clarifying info: A nibble (also called a half-byte) is a binary word of length of 4 bit, has 2⁴=16 possible values and can be represent by a single hexadecimal digit. The "nibble mode" works as follows (quoting the zytrax dns book):

[type] n or N: defines a nibble format in which each nibble of the iterated value (expressed as a hex number in lower case (n) or upper case (N)) is reversed and separated with dots.

It was (I think) added to be able to easily generate IPv6 reverse records in the ip6.arpa namespace, as defined by RFC1886. With it you can do things like this

$GENERATE 0-65535/1 0.0.0.0.${0,7,N}.4.0.0.0.3.0.0.0.2.0.0.0.1.0.0.0.0.0.0.0.1.2.3.4.ip6.arpa. PTR $.example.org.

to generate reverse records for the IPv6 addresses 4321:0:1:2:3:4:0:0 to 4321:0:1:2:3:4:ffff:0.

What makes this mode "special" is that it's the only one that 1) uses a separator in its output and 2) that separator is the dot which is the label separator in dns. The mentioned issue is that if the specified width is even, the generated part will end with a dot. All of these are equal:

a.0.0. IN A 1.0.0.10
$GENERATE 10-10/1 ${0,1,N}.0.0. A 1.0.0.$
$GENERATE 10-10/1 ${0,2,N}0.0. A 1.0.0.$
$GENERATE 10-10/1 ${0,3,N}.0. A 1.0.0.$
$GENERATE 10-10/1 ${0,4,N}0. A 1.0.0.$
$GENERATE 10-10/1 ${0,5,N}. A 1.0.0.$
$GENERATE 10-10/1 ${0,6,N} A 1.0.0.$

Depending on if and what comes after the generated part, the name will be absolute or origin-relative. If it is absolute and not within the origin, it will be silently discarded.

$ORIGIN example.org.
; these work
$GENERATE 10-10/1 ${0,1,N}.example.org. A 1.0.0.$
$GENERATE 10-10/1 ${0,2,N}example.org. A 1.0.0.$
$GENERATE 10-10/1 ${0,1,N} A 1.0.0.$
; this is discarded
$GENERATE 10-10/1 ${0,2,N} A 1.0.0.$

The discarding behaviour was already there, it is not exclusive to nibbles.

$ORIGIN example.org.
; this works
$GENERATE 10-10/1 $ A 1.0.0.$
; this is discarded
$GENERATE 10-10/1 $.example.net. A 1.0.0.$

corubba avatar Aug 09 '22 18:08 corubba

After reading the BIND docs, I get it the issue with weird widths. I'm ok with this now as if people enter weird widths, surprise is expected.

rthalley avatar Aug 10 '22 13:08 rthalley

Thanks!

rthalley avatar Aug 14 '22 16:08 rthalley