--- /dev/null
+adns debug: using nameserver 172.29.199.224
--- /dev/null
+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
--- /dev/null
+./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
--- /dev/null
+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
--- /dev/null
+./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
--- /dev/null
+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
--- /dev/null
+./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
--- /dev/null
+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
--- /dev/null
+./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
--- /dev/null
+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
--- /dev/null
+./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
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<NREVDOMAINS; rpd++, i++, d <<= 1) {
+ if (!(f & d)) continue;
+ if (labnum >= 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<NREVDOMAINS; rpd++, i++, d <<= 1) {
+ if (!(f & d)) continue;
+ if (nlabels >= 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;
+}
#define DNS_CLASS_IN 1
#define DNS_INADDR_ARPA "in-addr", "arpa"
+#define DNS_IP6_ARPA "ip6", "arpa"
#define MAX_POLLFDS ADNS_POLLFDS_RECOMMENDED
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 {
union {
struct {
+ adns_rrtype rev_rrtype;
struct af_addr addr;
} ptr;
} tinfo; /* type-specific state for the query itself: zero-init if you
* 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 */
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;
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,
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;
}
}
queried= &parent->ctx.tinfo.ptr.addr;
- assert(cans->type == adns_r_a);
for (i=0, found=cans->rrs.bytes; i<cans->nrrs; 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;
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;
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;