feat: support recursive query from authoritive servers
Hi @natesales
Please review this PR.
I propose to add recursive query support to q for the convenience for dns debugging or learning.
A new option --recursive has been introduced to enable the recursive mode.
In this mode, q will first query the root server hints from iana.org via https protocol. And then, it will choose whether to use the A or AAAA address of the first root servers, and do the query recursively. Besides, we can also use the -4 option to force use the ipv4 address.
After each round of query, q will choose the first A/AAAA record from extra fields as the server for next round. The query loop will continue until q get some answers. This PR choose the first NS server for stable output, other chosen algorithm maybe adopted.
As the authoritative servers for parent zone will only respond response with authority and extra fields, I choose to enable the --trace option for recursive mode, so that there is no need to add extra logic to display the information of the authoritative servers.
Please give your comments. Thank you.
Here is one usage example
go run . a zz.ac --recursive
DEBU[0000] Server(s): [198.41.0.4]
DEBU[0000] Using server 198.41.0.4:53 with transport plain
DEBU[0000] Using UDP with TCP fallback: 198.41.0.4:53
Question:
zz.ac. A
Authority:
ac. 48h NS a0.nic.ac.
ac. 48h NS a2.nic.ac.
ac. 48h NS b0.nic.ac.
ac. 48h NS c0.nic.ac.
Additional:
a0.nic.ac. 48h A 65.22.160.1
b0.nic.ac. 48h A 65.22.161.1
c0.nic.ac. 48h A 65.22.162.1
a2.nic.ac. 48h A 65.22.163.1
a0.nic.ac. 48h AAAA 2a01:8840:9e::1
b0.nic.ac. 48h AAAA 2a01:8840:9f::1
c0.nic.ac. 48h AAAA 2a01:8840:a0::1
a2.nic.ac. 48h AAAA 2a01:8840:a1::1
Stats:
Received 371 B from 198.41.0.4:53 in 249.2ms (00:07:11 06-14-2025 CST)
Opcode: QUERY Status: NOERROR ID 13389: Flags: qr rd (1 Q 0 A 4 N 8 E)
DEBU[0001] Using server 65.22.162.1:53 with transport plain
DEBU[0001] Using UDP with TCP fallback: 65.22.162.1:53
Question:
zz.ac. A
Authority:
zz.ac. 1h NS ns1.zz.ac.
zz.ac. 1h NS ns2.zz.ac.
zz.ac. 1h NS ns3.zz.ac.
zz.ac. 1h NS ns4.zz.ac.
Additional:
ns1.zz.ac. 1h A 122.9.71.163
ns4.zz.ac. 1h A 140.245.102.133
ns2.zz.ac. 1h A 154.21.82.127
ns3.zz.ac. 1h A 77.90.40.193
ns1.zz.ac. 1h AAAA 2407:c080:801:fffe::7a09:47a3
ns4.zz.ac. 1h AAAA 2603:c024:4516:2700:2646:d2c:e894:c0b4
ns2.zz.ac. 1h AAAA 2605:52c0:2:11b2::
ns3.zz.ac. 1h AAAA 2a0f:85c1:b73:c7::a
Stats:
Received 383 B from 65.22.162.1:53 in 361.2ms (00:07:11 06-14-2025 CST)
Opcode: QUERY Status: NOERROR ID 13389: Flags: qr rd (1 Q 0 A 4 N 8 E)
DEBU[0001] Using server 122.9.71.163:53 with transport plain
DEBU[0001] Using UDP with TCP fallback: 122.9.71.163:53
Question:
zz.ac. A
Answer:
zz.ac. 5m A 154.21.82.127
Authority:
zz.ac. 5m NS ns1.zz.ac.
zz.ac. 5m NS ns2.zz.ac.
zz.ac. 5m NS ns3.zz.ac.
zz.ac. 5m NS ns4.zz.ac.
Stats:
Received 156 B from 122.9.71.163:53 in 10.2ms (00:07:11 06-14-2025 CST)
Opcode: QUERY Status: NOERROR ID 13389: Flags: qr aa rd (1 Q 1 A 4 N 0 E)