From: Mark Wooding Date: Sat, 24 May 2014 13:00:03 +0000 (+0100) Subject: src/: Support IPv6 reverse queries. X-Git-Tag: adns-1.5.0-rc0~80 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=adns.git;a=commitdiff_plain;h=51cb3de39ef4e85d2efa7d167dc531d04500a525;ds=sidebyside src/: Support IPv6 reverse queries. This involves moving most of the label parser in ckl_ptr, and the reverse-domain constructor, into addrfam and teaching them about IPv6. The label parser is a little tricky because it involves keeping track of a parse state for each possible address family until we run out of possibilities or the parse is complete. Moving the reverse-domain constructor introduces a slightly unpleasant hack: because knowledge of the right reverse-lookup zone belongs in addrfam, we get adns_submit_reverse to pass a sentinel through _reverse_any to addrfam. Signed-off-by: Mark Wooding --- diff --git a/regress/case-dh-ptr-aaaa.err b/regress/case-dh-ptr-aaaa.err new file mode 100644 index 0000000..67419fb --- /dev/null +++ b/regress/case-dh-ptr-aaaa.err @@ -0,0 +1 @@ +adns debug: using nameserver 172.29.199.224 diff --git a/regress/case-dh-ptr-aaaa.out b/regress/case-dh-ptr-aaaa.out new file mode 100644 index 0000000..64060d2 --- /dev/null +++ b/regress/case-dh-ptr-aaaa.out @@ -0,0 +1,2 @@ +4.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.9.d.1.0.8.a.b.0.1.0.0.2.ip6.arpa PTR stratocaster.distorted.org.uk +rc=0 diff --git a/regress/case-dh-ptr-aaaa.sys b/regress/case-dh-ptr-aaaa.sys new file mode 100644 index 0000000..5b9f983 --- /dev/null +++ b/regress/case-dh-ptr-aaaa.sys @@ -0,0 +1,68 @@ +./adnshost distorted +-i2001:ba8:1d9:2::4 + start 1401919808.588362 + socket type=SOCK_DGRAM + socket=6 + +0.000058 + fcntl fd=6 cmd=F_GETFL + fcntl=~O_NONBLOCK&... + +0.000031 + fcntl fd=6 cmd=F_SETFL O_NONBLOCK|... + fcntl=OK + +0.000026 + sendto fd=6 addr=172.29.199.224:53 + 311f0100 00010000 00000000 01340130 01300130 01300130 01300130 01300130 + 01300130 01300130 01300130 01320130 01300130 01390164 01310130 01380161 + 01620130 01310130 01300132 03697036 04617270 6100000c 0001. + sendto=90 + +0.000233 + select max=7 rfds=[6] wfds=[] efds=[] to=1.999767 + select=1 rfds=[6] wfds=[] efds=[] + +0.004488 + recvfrom fd=6 buflen=512 + recvfrom=OK addr=172.29.199.224:53 + 311f8580 00010001 00040008 01340130 01300130 01300130 01300130 01300130 + 01300130 01300130 01300130 01320130 01300130 01390164 01310130 01380161 + 01620130 01310130 01300132 03697036 04617270 6100000c 0001c00c 000c0001 + 00003840 001f0c73 74726174 6f636173 74657209 64697374 6f727465 64036f72 + 6702756b 00c03400 02000100 00384000 0d0a7465 6c656361 73746572 c073c034 + 00020001 00003840 00090672 61646975 73c073c0 34000200 01000038 40000c09 + 70726563 6973696f 6ec073c0 34000200 01000038 40000a07 76616d70 697265c0 + 73c0aa00 01000100 00384000 04ac1dc7 01c0aa00 1c000100 00384000 10200104 + 70974000 01000000 00000000 01c0d700 01000100 00384000 04ac1dc7 05c0d700 + 1c000100 00384000 10200104 70974000 01000000 00000000 05c0bf00 01000100 + 00384000 04ac1dc7 b2c0bf00 1c000100 00384000 1020010b a801d900 02000000 + 00000000 02c09100 01000100 00384000 04ac1dc7 b3c09100 1c000100 00384000 + 1020010b a801d900 02000000 00000000 03. + +0.000405 + sendto fd=6 addr=172.29.199.224:53 + 31200100 00010000 00000000 0c737472 61746f63 61737465 72096469 73746f72 + 74656403 6f726702 756b0000 1c0001. + sendto=47 + +0.000175 + recvfrom fd=6 buflen=512 + recvfrom=EAGAIN + +0.000040 + select max=7 rfds=[6] wfds=[] efds=[] to=1.999380 + select=1 rfds=[6] wfds=[] efds=[] + +0.002002 + recvfrom fd=6 buflen=512 + recvfrom=OK addr=172.29.199.224:53 + 31208580 00010001 00040008 0c737472 61746f63 61737465 72096469 73746f72 + 74656403 6f726702 756b0000 1c0001c0 0c001c00 01000038 40001020 010ba801 + d9000200 00000000 000004c0 19000200 01000038 4000100a 74656c65 63617374 + 6572026e 73c019c0 19000200 01000038 40000c09 70726563 6973696f 6ec062c0 + 19000200 01000038 40000906 72616469 7573c062 c0190002 00010000 3840000a + 0776616d 70697265 c062c08b 00010001 00003840 0004ac1d c701c08b 001c0001 + 00003840 00102001 04709740 00010000 00000000 0001c0a0 00010001 00003840 + 0004ac1d c705c0a0 001c0001 00003840 00102001 04709740 00010000 00000000 + 0005c073 00010001 00003840 0004ac1d c7b2c073 001c0001 00003840 00102001 + 0ba801d9 00020000 00000000 0002c057 00010001 00003840 0004ac1d c7b3c057 + 001c0001 00003840 00102001 0ba801d9 00020000 00000000 0003. + +0.000280 + recvfrom fd=6 buflen=512 + recvfrom=EAGAIN + +0.000051 + close fd=6 + close=OK + +0.000134 diff --git a/regress/case-ptr-aaaa-check.err b/regress/case-ptr-aaaa-check.err new file mode 100644 index 0000000..e69de29 diff --git a/regress/case-ptr-aaaa-check.out b/regress/case-ptr-aaaa-check.out new file mode 100644 index 0000000..b2c9af8 --- /dev/null +++ b/regress/case-ptr-aaaa-check.out @@ -0,0 +1,5 @@ +adns debug: using nameserver 172.29.199.224 +4.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.9.d.1.0.8.a.b.0.1.0.0.2.ip6.arpa flags 0 type 65548 PTR(checked) submitted +4.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.9.d.1.0.8.a.b.0.1.0.0.2.ip6.arpa flags 0 type PTR(checked): OK; nrrs=1; cname=$; owner=$; ttl=14400 + stratocaster.distorted.org.uk +rc=0 diff --git a/regress/case-ptr-aaaa-check.sys b/regress/case-ptr-aaaa-check.sys new file mode 100644 index 0000000..c536b5f --- /dev/null +++ b/regress/case-ptr-aaaa-check.sys @@ -0,0 +1,68 @@ +./adnstest distorted +:65548 4.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.9.d.1.0.8.a.b.0.1.0.0.2.ip6.arpa + start 1401919115.064959 + socket type=SOCK_DGRAM + socket=6 + +0.000064 + fcntl fd=6 cmd=F_GETFL + fcntl=~O_NONBLOCK&... + +0.000031 + fcntl fd=6 cmd=F_SETFL O_NONBLOCK|... + fcntl=OK + +0.000027 + sendto fd=6 addr=172.29.199.224:53 + 311f0100 00010000 00000000 01340130 01300130 01300130 01300130 01300130 + 01300130 01300130 01300130 01320130 01300130 01390164 01310130 01380161 + 01620130 01310130 01300132 03697036 04617270 6100000c 0001. + sendto=90 + +0.000266 + select max=7 rfds=[6] wfds=[] efds=[] to=1.999734 + select=1 rfds=[6] wfds=[] efds=[] + +0.003844 + recvfrom fd=6 buflen=512 + recvfrom=OK addr=172.29.199.224:53 + 311f8580 00010001 00040008 01340130 01300130 01300130 01300130 01300130 + 01300130 01300130 01300130 01320130 01300130 01390164 01310130 01380161 + 01620130 01310130 01300132 03697036 04617270 6100000c 0001c00c 000c0001 + 00003840 001f0c73 74726174 6f636173 74657209 64697374 6f727465 64036f72 + 6702756b 00c03400 02000100 00384000 0c097072 65636973 696f6ec0 73c03400 + 02000100 00384000 09067261 64697573 c073c034 00020001 00003840 000d0a74 + 656c6563 61737465 72c073c0 34000200 01000038 40000a07 76616d70 697265c0 + 73c0a900 01000100 00384000 04ac1dc7 01c0a900 1c000100 00384000 10200104 + 70974000 01000000 00000000 01c0d700 01000100 00384000 04ac1dc7 05c0d700 + 1c000100 00384000 10200104 70974000 01000000 00000000 05c09100 01000100 + 00384000 04ac1dc7 b2c09100 1c000100 00384000 1020010b a801d900 02000000 + 00000000 02c0be00 01000100 00384000 04ac1dc7 b3c0be00 1c000100 00384000 + 1020010b a801d900 02000000 00000000 03. + +0.000334 + sendto fd=6 addr=172.29.199.224:53 + 31200100 00010000 00000000 0c737472 61746f63 61737465 72096469 73746f72 + 74656403 6f726702 756b0000 1c0001. + sendto=47 + +0.000139 + recvfrom fd=6 buflen=512 + recvfrom=EAGAIN + +0.000032 + select max=7 rfds=[6] wfds=[] efds=[] to=1.999495 + select=1 rfds=[6] wfds=[] efds=[] + +0.001799 + recvfrom fd=6 buflen=512 + recvfrom=OK addr=172.29.199.224:53 + 31208580 00010001 00040008 0c737472 61746f63 61737465 72096469 73746f72 + 74656403 6f726702 756b0000 1c0001c0 0c001c00 01000038 40001020 010ba801 + d9000200 00000000 000004c0 19000200 01000038 40000d07 76616d70 69726502 + 6e73c019 c0190002 00010000 3840000d 0a74656c 65636173 746572c0 5fc01900 + 02000100 00384000 0c097072 65636973 696f6ec0 5fc01900 02000100 00384000 + 09067261 64697573 c05fc0a1 00010001 00003840 0004ac1d c701c0a1 001c0001 + 00003840 00102001 04709740 00010000 00000000 0001c057 00010001 00003840 + 0004ac1d c705c057 001c0001 00003840 00102001 04709740 00010000 00000000 + 0005c089 00010001 00003840 0004ac1d c7b2c089 001c0001 00003840 00102001 + 0ba801d9 00020000 00000000 0002c070 00010001 00003840 0004ac1d c7b3c070 + 001c0001 00003840 00102001 0ba801d9 00020000 00000000 0003. + +0.000284 + recvfrom fd=6 buflen=512 + recvfrom=EAGAIN + +0.000046 + close fd=6 + close=OK + +0.000075 diff --git a/regress/case-ptr-aaaa-mismatch.err b/regress/case-ptr-aaaa-mismatch.err new file mode 100644 index 0000000..e69de29 diff --git a/regress/case-ptr-aaaa-mismatch.out b/regress/case-ptr-aaaa-mismatch.out new file mode 100644 index 0000000..04f1f2b --- /dev/null +++ b/regress/case-ptr-aaaa-mismatch.out @@ -0,0 +1,4 @@ +adns debug: using nameserver 172.29.199.224 +4.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.9.d.1.0.8.b.d.0.1.0.0.2.ip6.arpa flags 0 type 65548 PTR(checked) submitted +4.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.9.d.1.0.8.b.d.0.1.0.0.2.ip6.arpa flags 0 type PTR(checked): Inconsistent resource records in DNS; nrrs=0; cname=$; owner=$; ttl=14400 +rc=0 diff --git a/regress/case-ptr-aaaa-mismatch.sys b/regress/case-ptr-aaaa-mismatch.sys new file mode 100644 index 0000000..057f06c --- /dev/null +++ b/regress/case-ptr-aaaa-mismatch.sys @@ -0,0 +1,68 @@ +./adnstest distorted +:65548 4.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.9.d.1.0.8.b.d.0.1.0.0.2.ip6.arpa + start 1401919322.902230 + socket type=SOCK_DGRAM + socket=6 + +0.000061 + fcntl fd=6 cmd=F_GETFL + fcntl=~O_NONBLOCK&... + +0.000031 + fcntl fd=6 cmd=F_SETFL O_NONBLOCK|... + fcntl=OK + +0.000026 + sendto fd=6 addr=172.29.199.224:53 + 311f0100 00010000 00000000 01340130 01300130 01300130 01300130 01300130 + 01300130 01300130 01300130 01320130 01300130 01390164 01310130 01380162 + 01640130 01310130 01300132 03697036 04617270 6100000c 0001. + sendto=90 + +0.000410 + select max=7 rfds=[6] wfds=[] efds=[] to=1.999590 + select=1 rfds=[6] wfds=[] efds=[] + +0.003725 + recvfrom fd=6 buflen=512 + recvfrom=OK addr=172.29.199.224:53 + 311f8580 00010001 00040008 01340130 01300130 01300130 01300130 01300130 + 01300130 01300130 01300130 01320130 01300130 01390164 01310130 01380162 + 01640130 01310130 01300132 03697036 04617270 6100000c 0001c00c 000c0001 + 00003840 001f0c73 74726174 6f636173 74657209 64697374 6f727465 64036f72 + 6702756b 00c03400 02000100 00384000 0c097072 65636973 696f6ec0 73c03400 + 02000100 00384000 0d0a7465 6c656361 73746572 c073c034 00020001 00003840 + 00090672 61646975 73c073c0 34000200 01000038 40000a07 76616d70 697265c0 + 73c0c200 01000100 00384000 04ac1dc7 01c0c200 1c000100 00384000 10200104 + 70974000 01000000 00000000 01c0d700 01000100 00384000 04ac1dc7 05c0d700 + 1c000100 00384000 10200104 70974000 01000000 00000000 05c09100 01000100 + 00384000 04ac1dc7 b2c09100 1c000100 00384000 1020010b a801d900 02000000 + 00000000 02c0a900 01000100 00384000 04ac1dc7 b3c0a900 1c000100 00384000 + 1020010b a801d900 02000000 00000000 03. + +0.000340 + sendto fd=6 addr=172.29.199.224:53 + 31200100 00010000 00000000 0c737472 61746f63 61737465 72096469 73746f72 + 74656403 6f726702 756b0000 1c0001. + sendto=47 + +0.000244 + recvfrom fd=6 buflen=512 + recvfrom=EAGAIN + +0.000035 + select max=7 rfds=[6] wfds=[] efds=[] to=1.999381 + select=1 rfds=[6] wfds=[] efds=[] + +0.001587 + recvfrom fd=6 buflen=512 + recvfrom=OK addr=172.29.199.224:53 + 31208580 00010001 00040008 0c737472 61746f63 61737465 72096469 73746f72 + 74656403 6f726702 756b0000 1c0001c0 0c001c00 01000038 40001020 010ba801 + d9000200 00000000 000004c0 19000200 01000038 40000c06 72616469 7573026e + 73c019c0 19000200 01000038 40000a07 76616d70 697265c0 5ec01900 02000100 + 00384000 0c097072 65636973 696f6ec0 5ec01900 02000100 00384000 0d0a7465 + 6c656361 73746572 c05ec057 00010001 00003840 0004ac1d c701c057 001c0001 + 00003840 00102001 04709740 00010000 00000000 0001c06f 00010001 00003840 + 0004ac1d c705c06f 001c0001 00003840 00102001 04709740 00010000 00000000 + 0005c085 00010001 00003840 0004ac1d c7b2c085 001c0001 00003840 00102001 + 0ba801d9 00020000 00000000 0002c09d 00010001 00003840 0004ac1d c7b3c09d + 001c0001 00003840 00102001 0ba801d9 00020000 00000000 0003. + +0.000289 + recvfrom fd=6 buflen=512 + recvfrom=EAGAIN + +0.000048 + close fd=6 + close=OK + +0.000546 diff --git a/regress/case-ptr-aaaa-plain.err b/regress/case-ptr-aaaa-plain.err new file mode 100644 index 0000000..e69de29 diff --git a/regress/case-ptr-aaaa-plain.out b/regress/case-ptr-aaaa-plain.out new file mode 100644 index 0000000..63e72ad --- /dev/null +++ b/regress/case-ptr-aaaa-plain.out @@ -0,0 +1,5 @@ +adns debug: using nameserver 172.29.199.224 +4.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.9.d.1.0.8.a.b.0.1.0.0.2.ip6.arpa flags 0 type 12 PTR(raw) submitted +4.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.9.d.1.0.8.a.b.0.1.0.0.2.ip6.arpa flags 0 type PTR(raw): OK; nrrs=1; cname=$; owner=$; ttl=14400 + stratocaster.distorted.org.uk +rc=0 diff --git a/regress/case-ptr-aaaa-plain.sys b/regress/case-ptr-aaaa-plain.sys new file mode 100644 index 0000000..d09ce17 --- /dev/null +++ b/regress/case-ptr-aaaa-plain.sys @@ -0,0 +1,43 @@ +./adnstest distorted +:12 4.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.9.d.1.0.8.a.b.0.1.0.0.2.ip6.arpa + start 1401918956.635299 + socket type=SOCK_DGRAM + socket=6 + +0.000060 + fcntl fd=6 cmd=F_GETFL + fcntl=~O_NONBLOCK&... + +0.000032 + fcntl fd=6 cmd=F_SETFL O_NONBLOCK|... + fcntl=OK + +0.000026 + sendto fd=6 addr=172.29.199.224:53 + 311f0100 00010000 00000000 01340130 01300130 01300130 01300130 01300130 + 01300130 01300130 01300130 01320130 01300130 01390164 01310130 01380161 + 01620130 01310130 01300132 03697036 04617270 6100000c 0001. + sendto=90 + +0.000219 + select max=7 rfds=[6] wfds=[] efds=[] to=1.999781 + select=1 rfds=[6] wfds=[] efds=[] + +0.002107 + recvfrom fd=6 buflen=512 + recvfrom=OK addr=172.29.199.224:53 + 311f8580 00010001 00040008 01340130 01300130 01300130 01300130 01300130 + 01300130 01300130 01300130 01320130 01300130 01390164 01310130 01380161 + 01620130 01310130 01300132 03697036 04617270 6100000c 0001c00c 000c0001 + 00003840 001f0c73 74726174 6f636173 74657209 64697374 6f727465 64036f72 + 6702756b 00c03400 02000100 00384000 0a077661 6d706972 65c073c0 34000200 + 01000038 40000d0a 74656c65 63617374 6572c073 c0340002 00010000 3840000c + 09707265 63697369 6f6ec073 c0340002 00010000 38400009 06726164 697573c0 + 73c0d800 01000100 00384000 04ac1dc7 01c0d800 1c000100 00384000 10200104 + 70974000 01000000 00000000 01c09100 01000100 00384000 04ac1dc7 05c09100 + 1c000100 00384000 10200104 70974000 01000000 00000000 05c0c000 01000100 + 00384000 04ac1dc7 b2c0c000 1c000100 00384000 1020010b a801d900 02000000 + 00000000 02c0a700 01000100 00384000 04ac1dc7 b3c0a700 1c000100 00384000 + 1020010b a801d900 02000000 00000000 03. + +0.000349 + recvfrom fd=6 buflen=512 + recvfrom=EAGAIN + +0.000072 + close fd=6 + close=OK + +0.000081 diff --git a/regress/case-ptr-aaaa.err b/regress/case-ptr-aaaa.err new file mode 100644 index 0000000..e69de29 diff --git a/regress/case-ptr-aaaa.out b/regress/case-ptr-aaaa.out new file mode 100644 index 0000000..b2c9af8 --- /dev/null +++ b/regress/case-ptr-aaaa.out @@ -0,0 +1,5 @@ +adns debug: using nameserver 172.29.199.224 +4.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.9.d.1.0.8.a.b.0.1.0.0.2.ip6.arpa flags 0 type 65548 PTR(checked) submitted +4.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.9.d.1.0.8.a.b.0.1.0.0.2.ip6.arpa flags 0 type PTR(checked): OK; nrrs=1; cname=$; owner=$; ttl=14400 + stratocaster.distorted.org.uk +rc=0 diff --git a/regress/case-ptr-aaaa.sys b/regress/case-ptr-aaaa.sys new file mode 100644 index 0000000..60fa010 --- /dev/null +++ b/regress/case-ptr-aaaa.sys @@ -0,0 +1,68 @@ +./adnstest distorted +:65548 4.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.9.d.1.0.8.a.b.0.1.0.0.2.ip6.arpa + start 1401919090.054985 + socket type=SOCK_DGRAM + socket=6 + +0.000061 + fcntl fd=6 cmd=F_GETFL + fcntl=~O_NONBLOCK&... + +0.000030 + fcntl fd=6 cmd=F_SETFL O_NONBLOCK|... + fcntl=OK + +0.000026 + sendto fd=6 addr=172.29.199.224:53 + 311f0100 00010000 00000000 01340130 01300130 01300130 01300130 01300130 + 01300130 01300130 01300130 01320130 01300130 01390164 01310130 01380161 + 01620130 01310130 01300132 03697036 04617270 6100000c 0001. + sendto=90 + +0.000227 + select max=7 rfds=[6] wfds=[] efds=[] to=1.999773 + select=1 rfds=[6] wfds=[] efds=[] + +0.003800 + recvfrom fd=6 buflen=512 + recvfrom=OK addr=172.29.199.224:53 + 311f8580 00010001 00040008 01340130 01300130 01300130 01300130 01300130 + 01300130 01300130 01300130 01320130 01300130 01390164 01310130 01380161 + 01620130 01310130 01300132 03697036 04617270 6100000c 0001c00c 000c0001 + 00003840 001f0c73 74726174 6f636173 74657209 64697374 6f727465 64036f72 + 6702756b 00c03400 02000100 00384000 0c097072 65636973 696f6ec0 73c03400 + 02000100 00384000 0a077661 6d706972 65c073c0 34000200 01000038 40000906 + 72616469 7573c073 c0340002 00010000 3840000d 0a74656c 65636173 746572c0 + 73c0bf00 01000100 00384000 04ac1dc7 01c0bf00 1c000100 00384000 10200104 + 70974000 01000000 00000000 01c0a900 01000100 00384000 04ac1dc7 05c0a900 + 1c000100 00384000 10200104 70974000 01000000 00000000 05c09100 01000100 + 00384000 04ac1dc7 b2c09100 1c000100 00384000 1020010b a801d900 02000000 + 00000000 02c0d400 01000100 00384000 04ac1dc7 b3c0d400 1c000100 00384000 + 1020010b a801d900 02000000 00000000 03. + +0.000338 + sendto fd=6 addr=172.29.199.224:53 + 31200100 00010000 00000000 0c737472 61746f63 61737465 72096469 73746f72 + 74656403 6f726702 756b0000 1c0001. + sendto=47 + +0.000129 + recvfrom fd=6 buflen=512 + recvfrom=EAGAIN + +0.000031 + select max=7 rfds=[6] wfds=[] efds=[] to=1.999502 + select=1 rfds=[6] wfds=[] efds=[] + +0.001827 + recvfrom fd=6 buflen=512 + recvfrom=OK addr=172.29.199.224:53 + 31208580 00010001 00040008 0c737472 61746f63 61737465 72096469 73746f72 + 74656403 6f726702 756b0000 1c0001c0 0c001c00 01000038 40001020 010ba801 + d9000200 00000000 000004c0 19000200 01000038 4000100a 74656c65 63617374 + 6572026e 73c019c0 19000200 01000038 40000906 72616469 7573c062 c0190002 + 00010000 3840000a 0776616d 70697265 c062c019 00020001 00003840 000c0970 + 72656369 73696f6e c062c073 00010001 00003840 0004ac1d c701c073 001c0001 + 00003840 00102001 04709740 00010000 00000000 0001c088 00010001 00003840 + 0004ac1d c705c088 001c0001 00003840 00102001 04709740 00010000 00000000 + 0005c09e 00010001 00003840 0004ac1d c7b2c09e 001c0001 00003840 00102001 + 0ba801d9 00020000 00000000 0002c057 00010001 00003840 0004ac1d c7b3c057 + 001c0001 00003840 00102001 0ba801d9 00020000 00000000 0003. + +0.000308 + recvfrom fd=6 buflen=512 + recvfrom=EAGAIN + +0.000056 + close fd=6 + close=OK + +0.000088 diff --git a/src/addrfam.c b/src/addrfam.c index 28bf128..3bddabd 100644 --- a/src/addrfam.c +++ b/src/addrfam.c @@ -455,3 +455,181 @@ char *adns__sockaddr_ntoa(const struct sockaddr *sa, char *buf) { assert(!err); return buf; } + +/* + * Reverse-domain parsing and construction. + */ + +int adns__make_reverse_domain(const struct sockaddr *sa, const char *zone, + char **buf_io, size_t bufsz, + char **buf_free_r) { + size_t req; + char *p; + unsigned c, y; + unsigned long aa; + const unsigned char *ap; + int i, j; + + switch (sa->sa_family) { + AF_CASES(af); + af_inet: + req= 4 * 4; + if (!zone) zone= "in-addr.arpa"; + break; + af_inet6: + req = 2 * 32; + if (!zone) zone= "ip6.arpa"; + break; + default: + return ENOSYS; + } + + req += strlen(zone) + 1; + if (req <= bufsz) + p= *buf_io; + else { + p= malloc(req); if (!p) return errno; + *buf_free_r = p; + } + + *buf_io= p; + switch (sa->sa_family) { + AF_CASES(bf); + bf_inet: + aa= ntohl(CSIN(sa)->sin_addr.s_addr); + for (i=0; i<4; i++) { + p += sprintf(p, "%d", (int)(aa & 0xff)); + *p++= '.'; + aa >>= 8; + } + break; + bf_inet6: + ap= CSIN6(sa)->sin6_addr.s6_addr + 16; + for (i=0; i<16; i++) { + c= *--ap; + for (j=0; j<2; j++) { + y= c & 0xf; + *p++= (y < 10) ? y + '0' : y - 10 + 'a'; + c >>= 4; + *p++= '.'; + } + } + break; + default: + unknown_af(sa->sa_family); + } + + strcpy(p, zone); + return 0; +} + + +static int inet_rev_parsecomp(const char *p, size_t n) { + int i= 0; + if (n > 3) return -1; + + while (n--) { + if ('0' <= *p && *p <= '9') i= 10*i + *p++ - '0'; + else return -1; + } + return i; +} + +static void inet_rev_mkaddr(union gen_addr *addr, const byte *ipv) { + addr->v4.s_addr= htonl((ipv[3]<<24) | (ipv[2]<<16) | + (ipv[1]<<8) | (ipv[0])); +} + +static int inet6_rev_parsecomp(const char *p, size_t n) { + if (n != 1) return -1; + else if ('0' <= *p && *p <= '9') return *p - '0'; + else if ('a' <= *p && *p <= 'f') return *p - 'a' + 10; + else if ('A' <= *p && *p <= 'F') return *p - 'a' + 10; + else return -1; +} + +static void inet6_rev_mkaddr(union gen_addr *addr, const byte *ipv) { + unsigned char *a= addr->v6.s6_addr; + int i; + + for (i=0; i<16; i++) + a[i]= (ipv[31-2*i] << 4) | (ipv[30-2*i] << 0); +} + +static const struct revparse_domain { + int af; /* address family */ + int nrevlab; /* n of reverse-address labels */ + adns_rrtype rrtype; /* forward-lookup type */ + + int (*rev_parsecomp)(const char *p, size_t n); + /* parse a single component from a label; return the integer value, or -1 + * if it was unintelligible. + */ + + void (*rev_mkaddr)(union gen_addr *addr, const byte *ipv); + /* write out the parsed address from a vector of parsed components */ + + const char *const tail[3]; /* tail label names */ +} revparse_domains[NREVDOMAINS] = { + { AF_INET, 4, adns_r_a, inet_rev_parsecomp, inet_rev_mkaddr, + { DNS_INADDR_ARPA, 0 } }, + { AF_INET6, 32, adns_r_aaaa, inet6_rev_parsecomp, inet6_rev_mkaddr, + { DNS_IP6_ARPA, 0 } }, +}; + +#define REVDOMAIN_MAP(rps, labnum) \ + ((labnum) ? (rps)->map : (1 << NREVDOMAINS) - 1) + +int adns__revparse_label(struct revparse_state *rps, int labnum, + const char *label, int lablen) { + unsigned f= REVDOMAIN_MAP(rps, labnum); + const struct revparse_domain *rpd; + const char *tp; + unsigned d; + int i, ac; + + for (rpd=revparse_domains, i=0, d=1; i= rpd->nrevlab) { + tp = rpd->tail[labnum - rpd->nrevlab]; + if (!tp || strncmp(label, tp, lablen) != 0 || tp[lablen]) + goto mismatch; + } else { + ac= rpd->rev_parsecomp(label, lablen); + if (ac < 0) goto mismatch; + assert(labnum < sizeof(rps->ipv[i])); + rps->ipv[i][labnum]= ac; + } + continue; + + mismatch: + f &= ~d; + if (!f) return -1; + } + + rps->map= f; + return 0; +} + +int adns__revparse_done(struct revparse_state *rps, int nlabels, + adns_rrtype *rrtype_r, struct af_addr *addr_r) { + unsigned f= REVDOMAIN_MAP(rps, nlabels); + const struct revparse_domain *rpd; + unsigned d; + int i, found= -1; + + for (rpd=revparse_domains, i=0, d=1; i= rpd->nrevlab && !rpd->tail[nlabels - rpd->nrevlab]) + { found = i; continue; } + f &= ~d; + if (!f) return -1; + } + assert(found >= 0); assert(f == (1 << found)); + + rpd= &revparse_domains[found]; + *rrtype_r= rpd->rrtype; + addr_r->af= rpd->af; + rpd->rev_mkaddr(&addr_r->addr, rps->ipv[found]); + return 0; +} diff --git a/src/internal.h b/src/internal.h index 6c6a77e..baf2a29 100644 --- a/src/internal.h +++ b/src/internal.h @@ -69,6 +69,7 @@ typedef unsigned char byte; #define DNS_CLASS_IN 1 #define DNS_INADDR_ARPA "in-addr", "arpa" +#define DNS_IP6_ARPA "ip6", "arpa" #define MAX_POLLFDS ADNS_POLLFDS_RECOMMENDED @@ -131,8 +132,14 @@ union gen_addr { struct af_addr { int af; union gen_addr addr; }; +#define NREVDOMAINS 2 /* keep in sync with addrfam! */ +struct revparse_state { + unsigned map; /* which domains are still live */ + byte ipv[NREVDOMAINS][32]; /* address components so far */ +}; + union checklabel_state { - struct { byte ipv[4]; } ptr; + struct revparse_state ptr; }; typedef struct { @@ -141,6 +148,7 @@ typedef struct { union { struct { + adns_rrtype rev_rrtype; struct af_addr addr; } ptr; } tinfo; /* type-specific state for the query itself: zero-init if you @@ -438,6 +446,40 @@ char *adns__sockaddr_ntoa(const struct sockaddr *sa, char *buf); * ADNS_ADDR2TEXT_BUFLEN bytes long (unchecked). Return buf; can't fail. */ +extern int adns__make_reverse_domain(const struct sockaddr *sa, + const char *zone, + char **buf_io, size_t bufsz, + char **buf_free_r); +/* Construct a reverse domain string, given a socket address and a parent + * zone. If zone is null, then use the standard reverse-lookup zone for the + * address family. If the length of the resulting string is no larger than + * bufsz, then the result is stored starting at *buf_io; otherwise a new + * buffer is allocated is used, and a pointer to it is stored in both *buf_io + * and *buf_free_r (the latter of which should be null on entry). If + * something goes wrong, then an errno value is returned: ENOSYS if the + * address family of sa isn't recognized, or ENOMEM if the attempt to + * allocate an output buffer failed. + */ + +extern int adns__revparse_label(struct revparse_state *rps, int labnum, + const char *label, int lablen); +/* Parse a label in a reverse-domain name, given its index labnum (starting + * from zero), a pointer to its contents (which need not be null-terminated), + * and its length. The state in *rps is initialized implicitly when labnum + * is zero. + * + * Returns zero if the parse was successful, nonzero if the domain name is + * definitely invalid and the parse must be abandoned. + */ + +extern int adns__revparse_done(struct revparse_state *rps, int nlabels, + adns_rrtype *rrtype_r, struct af_addr *addr_r); +/* Finishes parsing a reverse-domain name, given the total number of labels + * in the name. On success, fills in the address in *addr_r, and the forward + * query type in *rrtype_r (because that turns out to be useful). Returns + * nonzero if the parse must be abandoned. + */ + /* From setup.c: */ int adns__setnonblock(adns_state ads, int fd); /* => errno value */ diff --git a/src/query.c b/src/query.c index 717cac0..c32acba 100644 --- a/src/query.c +++ b/src/query.c @@ -331,28 +331,15 @@ int adns_submit_reverse_any(adns_state ads, adns_queryflags flags, void *context, adns_query *query_r) { - const unsigned char *iaddr; - char *buf, *buf_free; + char *buf, *buf_free = 0; char shortbuf[100]; - int r, lreq; + int r; flags &= ~adns_qf_search; - if (addr->sa_family != AF_INET) return ENOSYS; - iaddr= (const unsigned char*) - &(((const struct sockaddr_in*)addr) -> sin_addr); - - lreq= strlen(zone) + 4*4 + 1; - if (lreq > sizeof(shortbuf)) { - buf= malloc(strlen(zone) + 4*4 + 1); - if (!buf) return errno; - buf_free= buf; - } else { - buf= shortbuf; - buf_free= 0; - } - sprintf(buf, "%d.%d.%d.%d.%s", iaddr[3], iaddr[2], iaddr[1], iaddr[0], zone); - + buf = shortbuf; + r= adns__make_reverse_domain(addr,zone, &buf,sizeof(shortbuf),&buf_free); + if (r) return r; r= adns_submit(ads,buf,type,flags,context,query_r); free(buf_free); return r; @@ -367,8 +354,7 @@ int adns_submit_reverse(adns_state ads, if (((type^adns_r_ptr) & adns_rrt_reprmask) && ((type^adns_r_ptr_raw) & adns_rrt_reprmask)) return EINVAL; - return adns_submit_reverse_any(ads,addr,"in-addr.arpa", - type,flags,context,query_r); + return adns_submit_reverse_any(ads,addr,0,type,flags,context,query_r); } int adns_synchronous(adns_state ads, diff --git a/src/types.c b/src/types.c index abe0c88..ac6b310 100644 --- a/src/types.c +++ b/src/types.c @@ -765,29 +765,14 @@ static adns_status cs_inthost(vbuf *vb, const void *datap) { static adns_status ckl_ptr(adns_state ads, adns_queryflags flags, union checklabel_state *cls, qcontext *ctx, int labnum, const char *label, int lablen) { - static const char *const (expectdomain[])= { DNS_INADDR_ARPA }; - char *ep; - const char *ed; - char labbuf[4]; - int l; - - if (labnum < 4) { - if (lablen<=0 || lablen>3) return adns_s_querydomainwrong; - memcpy(labbuf, label, lablen); - labbuf[lablen]= 0; - cls->ptr.ipv[3-labnum]= strtoul(labbuf,&ep,10); - if (*ep) return adns_s_querydomainwrong; - if (lablen>1 && *label=='0') return adns_s_querydomainwrong; - } else if (labnum < 4 + sizeof(expectdomain)/sizeof(*expectdomain)) { - ed= expectdomain[labnum-4]; - l= strlen(ed); - if (lablen != l || memcmp(label, ed, l)) return adns_s_querydomainwrong; + if (lablen) { + if (adns__revparse_label(&cls->ptr, labnum, label,lablen)) + return adns_s_querydomainwrong; } else { - if (lablen) return adns_s_querydomainwrong; - ctx->tinfo.ptr.addr.af= AF_INET; - ctx->tinfo.ptr.addr.addr.v4.s_addr= - htonl((cls->ptr.ipv[0]<<24) | (cls->ptr.ipv[1]<<16) | - (cls->ptr.ipv[2]<< 8) | (cls->ptr.ipv[3])); + if (adns__revparse_done(&cls->ptr, labnum, + &ctx->tinfo.ptr.rev_rrtype, + &ctx->tinfo.ptr.addr)) + return adns_s_querydomainwrong; } return adns_s_ok; } @@ -808,9 +793,9 @@ static void icb_ptr(adns_query parent, adns_query child) { } queried= &parent->ctx.tinfo.ptr.addr; - assert(cans->type == adns_r_a); for (i=0, found=cans->rrs.bytes; inrrs; i++, found+=cans->rrsz) { - if (adns__genaddr_equal_p(queried->af,&queried->addr, AF_INET,found)) { + if (adns__genaddr_equal_p(queried->af,&queried->addr, + parent->ctx.tinfo.ptr.addr.af,found)) { if (!parent->children.head) { adns__query_done(parent); return; @@ -828,6 +813,7 @@ static adns_status pa_ptr(const parseinfo *pai, int dmstart, int max, void *datap) { char **rrp= datap; adns_status st; + adns_rrtype rrtype= pai->qu->ctx.tinfo.ptr.rev_rrtype; int cbyte, id; adns_query nqu; qcontext ctx; @@ -840,16 +826,16 @@ static adns_status pa_ptr(const parseinfo *pai, int dmstart, st= adns__mkquery_frdgram(pai->ads, &pai->qu->vb, &id, pai->dgram, pai->dglen, dmstart, - adns_r_a, adns_qf_quoteok_query); + rrtype, adns_qf_quoteok_query); if (st) return st; ctx.ext= 0; ctx.callback= icb_ptr; memset(&ctx.pinfo,0,sizeof(ctx.pinfo)); memset(&ctx.tinfo,0,sizeof(ctx.tinfo)); - st= adns__internal_submit(pai->ads, &nqu, adns__findtype(adns_r_a), - adns_r_a, &pai->qu->vb, id, adns_qf_quoteok_query, - pai->now, &ctx); + st= adns__internal_submit(pai->ads, &nqu, adns__findtype(rrtype), + rrtype, &pai->qu->vb, id, + adns_qf_quoteok_query, pai->now, &ctx); if (st) return st; nqu->parent= pai->qu;