[fpc-pascal] netdb, TCP, and DNS queries
Noel Duffy
noelduffy at xtra.co.nz
Sun Dec 6 04:02:08 CET 2020
Hi all,
Following up on the work I've being doing to add support for DNS queries over TCP to netdb and to add support for querying all of the standard resource types such as MX, SOA, TXT, NS, etc, I've added the proposed changes to a note in the Bugtracker:
https://bugs.freepascal.org/view.php?id=37906#c127368
This isn't yet in patch form. I've just created a copy of netdb.pp and renamed it to newnetdb.pp. I'm posting about it now to get some feedback on it. The second file attached is a standalone Pascal project named dnsq.lpr that exercises the dns functions. It works just like the Unix program "dig". You give it a DNS resource type, one of A, AAAA, CNAME, PTR, NS, SOA, MX, or TXT, and a domain name. Some example usage:
./dnsq txt freepascal.org
- freepascal.org (TXT)
Answers: 1 NS: 0 Additional: 0 Length: 87 AnsStart: 20
-- Answers
freepascal.org 43200 TXT v=spf1 mx a:lists.freepascal.org a:mail.freepascal.org
$ ./dnsq ns freepascal.org
- freepascal.org (NS)
Answers: 3 NS: 0 Additional: 5 Length: 213 AnsStart: 20
-- Answers
freepascal.org 170198 NS dns1.easydns.com
freepascal.org 170198 NS dns3.easydns.ca
freepascal.org 170198 NS dns2.easydns.net
-- Additional Section
dns2.easydns.net 502 A 198.41.222.254
dns2.easydns.net 468 AAAA 2400:CB00:2049:0001::C629:DEFE
dns1.easydns.com 174 A 64.68.192.10
dns1.easydns.com 83 AAAA 2400:CB00:2049:0001::A29F:1835
dns3.easydns.ca 6 A 64.68.196.10
$ ./dnsq soa freepascal.org
- freepascal.org (SOA)
Answers: 1 NS: 0 Additional: 0 Length: 77 AnsStart: 20
-- Answers
freepascal.org 167820 SOA dns1.easydns.com zone.easydns.com, serial:1598197381, refresh:3600, retry:600, min:300, expire:604800
The code for dnsq is quite short and straightforward, imho. My hope is that, with a bit of polish, it may be suitable for addition to the set of sample projects included with fpc. In addition to showing queries for different resource types, it shows how to detect truncation and fall back to TCP.
I'm still working on tests for the code. Testing network code isn't easy to do, so I'm having to figure it out as I go.
As a general rule I've tried to minimize changes to existing code and if changes are necessary, to add new types rather than change old ones. Where I've added record types, I've tried to compose from existing record types so things are still defined just once. For instance, where I needed a TQueryData equivalent with a length field, I did it like this:
TQueryDataLength = packed record
length: Word;
hpl: TQueryData;
end;
I also created a new RR record type. I needed a resource record that preserves the RR name, because many queries return A and AAAA records in the additional section and it's impossible to use these without the name. For instance, see the NS query example I showed above, where five A and AAAA records get returned in the additional section.
Using the API is straightforward enough. You call DnsLookup with a domain name and a resource type. If that succeeds, you call GetRRRecords to get a dynamic array of resource records. To get the actual RRData, there are functions for each resource type. E.g, DNSRRGetText, DNSRRGetMX, and so on.
OK, that's probably enough for now. I'll be happy to go into more details or answer any questions about this code.
More information about the fpc-pascal
mailing list