Where it belongs, alongside the /etc/hosts check. The inner lookup() method is
really about talking to a specific DNS server.
Also, don't bail out on a empty name. An empty DNSName is actually '.' — a
single dot — aka the DNS root.
...just like we store m_lookup_cache, in other words.
This immediately lets us match on types: for instance we will now only resolve
1.0.0.127.in-addr.arpa to localhost if asked for type PTR, not for type A. In
the future, this could also let us have the same /etc/hosts name resolve
to *multiple* addresses.
DNSName can now take care of case conversion when comparing using traits.
It still intentionally doesn't implement operator ==; you have to explicitly
decide whether you want case-sensitive or case-insensitive comparison.
This change makes caches (and /etc/hosts) case-transparent: we will now match
domains if they're the same except for the case.
* DNSName knows how to randomize itself
* DNSPacket no longer constructs DNSQuestion instances, it receives an already
built DNSQuestion and just adds it to the list
* LookupServer::lookup() explicitly calls randomize_case() if it needs to
randomize the case.
This is a wrapper around a string representing a domain name (such as
"example.com"). It never has a trailing dot.
For now, this class doesn't do much except wrap the raw string. Subsequent
commits will add or move more functionality to it.
They're really the same thing: a DNS packet can contain both questions and
answers, and there's a single bit in the header that determines whether the
packet represents a query or a response. It'll be simpler for us to represent
both types of packets using the same class.
This class can be both serialized and deserialized to/from a raw DNS packet.
Now that we no longer depend on the textual IPC format, we can pass IP addresses
in the format most code actually has and needs it: in binary. The only places we
actually have to deal with textual address representation is:
* When reading /etc/hosts, we have to parse textual addresses & convert them to
binary;
* When doing reverse lookups, we have to form a pseudo-hostname of the form
x.x.x.x.in-addr.arpa.
So we do the conversion in those two cases.
This also increases uniformity between how we handle A (IPv4 address) and other
resource record types. Namely, we now store the raw binary data as received from
a DNS server.
The ad-hoc IPC we were doing with LookupServer was kinda gross. With this,
LookupServer is a regular IPC server. In the future, we want to add more APIs
for LookupServer to talk to its clients (such as DHCPClient telling LookupServer
about the DNS server discovered via DHCP, and DNS-SD client browsing for
services), which calls for a more expressive IPC format; this is what LibIPC is
perfect for.
While the LookupServer side is using the regular LibIPC mechanics and patterns,
the LibC side has to hand-roll LibIPC format serialization without actually
using LibIPC. We might be able to get rid of this in the future, but for now it
has to be like that. The good news is the format is not that bad at all.
We were ignoring everything but A records in DNS responses. This broke
reverse lookups which obviously want the PTR records.
Fix this by filtering on the requested record type instead of always A.