AsyncDNS
May 31st, 2008
I’m currently spending some time with implementing DNS on top of Mina. I were informed that there is already a DNS implementation available in Apache DS but I doubt that it is full featured (including client processing, IANA record types etc.) and as far as I know is based on Mina 1. So, I am still hacking a bit on it. It basically works the same way around like AsyncFCGI. The decoder returns all the decoded messages including every available translated bit to a Java object and you can simply create DnsRecords and send them over the wire without a need to struggle with all the low level protocol stuff. I also try to support both UDP and TCP based DNS within a single interface.
For now the protocol is implemented mostly, however I need to think about how to decode message contents into variable object types automatically (done) and what the truncation of DNS messages is all about in a real world test case (done). I also implemented a little example server for testing of the following natively understood record types:
- ARecord - Standard IPv4 “IN A” records
- AaaaRecord - IPv6 “IN AAAA” records
- PtrRecord - Reverse lookup “in-addr.arpa” records
- CnameRecord - CNAME records
- NsRecord - Nameserver authorities
- TxtRecord - Plain text records
- SpfRecord - The same as TXT but with the recently assigned record code
- MxRecord - Mail exchanger records holding preference and host
- SoaRecord - Zone of authority records
- DnsRecord - Everything else you can immagine
The example server is able to:
- serve the above record types represented by a simple Java class uppon request
- serve all the other possible record types using buffer contents
- be extended with all the record types you can think of
- count down the time to live automatically (ok, trivial ^^)
- use the DNS compression scheme but enforce compatbility by not compressing record contents
- lookup the authority if no matching answers were found (as recommended)
- work on both UDP and TCP connections using the same decoder and encoder pairs
- be not vulnerable for buffer overflows like C based servers are
- automatically truncate response records
- do round-robin on multiple result records
- understand type “IN ALL” queries
- serve the data in best non-blocking manner for optimal performance
- allow different datasources (Memory already implemented, File and DB are prototyped)
A client is in process to enable recursive lookups or usage as a DNS cache, too. I’m thinking about adding UPDATE/NOTIFY for synchronization of multiple servers also. Another point could be Dnslets (like the Apache FTP Server Ftplets) to check for responding hosts so that they could be deactivated while unreacheable (e.g. for high availability).
Download first preview (most of the code is still todo, but the server works):
- AsyncDNS Preview #1 (Initial)
- AsyncDNS Preview #2 (Datasources -> MemoryDatasource, DatabaseDatasource)
There are also other record types implemented as default “DnsRecord”s with untranslated buffer contents but I were not yet able to test them. So here comes everything but the kitchen sink:
Implemented record types:
/** IPv4 address */
A(1),
/** An authoritative nameserver */
NS(2),
/** A mail destination (Obsolete - use MX) */
MD(3),
/** A mail forwarder (Obsolete - use MX) */
MF(4),
/** The canonical name for an alias */
CNAME(5),
/** Marks the start of a zone of authority */
SOA(6),
/** A mailbox domain name (EXPERIMENTAL) */
MB(7),
/** A mail group member (EXPERIMENTAL) */
MG(8),
/** A mail rename domain name (EXPERIMENTAL) */
MR(9),
/** A null RR (EXPERIMENTAL) */
NULL(10),
/** A well known service description */
WKS(11),
/** A domain name pointer */
PTR(12),
/** Host information */
HINFO(13),
/** Mailbox or mail list information */
MINFO(14),
/** Mail exchange */
MX(15),
/** Text strings */
TXT(16),
/** Responsible person */
RP(17),
/** AFS Data Base location */
AFSDB(18),
/** X25 PSDN address */
X25(19),
/** ISDN address */
ISDN(20),
/** Route through */
RT(21),
/** Network service access point address */
NSAP(22),
/** NSAP pointer (obsolete) */
NSAP_PTR(23),
/** Cryptographic public key signature */
SIG(24),
/** Public key as used in DNSSEC */
KEY(25),
/** Pointer to X.400/RFC822 mail mapping information */
PX(26),
/** Geographical position (obsolete) */
GPOS(27),
/** IPv6 address */
AAAA(28),
/** Location information */
LOC(29),
/** Next domain */
NXT(30),
/** Endpoint Identifier */
EID(31),
/** Nimrod Locator */
NIMLOC(32),
/** Server selection */
SRV(33),
/** ATM Address */
ATMA(34),
/** Naming authority pointer */
NAPTR(35),
/** Key Exchanger */
KX(36),
/** CERT */
CERT(37),
/** Obsolete IPv6 address (use AAAA instead) */
A6(38),
/** DNAME */
DNAME(39),
/** SINK */
SINK(40),
/** OPT */
OPT(41),
/** APL */
APL(42),
/** Delegation signer */
DS(43),
/** SSH Key Fingerprint */
SSHFP(44),
/** IPSECKEY */
IPSECKEY(45),
/** RRSIG */
RRSIG(46),
/** NSEC */
NSEC(47),
/** DNSKEY */
DNSKEY(48),
/** DHCID */
DHCID(49),
/** NSEC3 */
NSEC3(50),
/** NSEC3PARAM */
NSEC3PARAM(51),
/** Host Identity Protocol */
HIP(55),
/** SPF */
SPF(99),
/** UNIFO */
UINFO(100),
/** UID */
UID(101),
/** GID */
GID(102),
/** UNSPEC */
UNSPEC(103),
/** Transaction key */
TKEY(249),
/** Transaction signature */
TSIG(250),
/** Incremental Transfer */
IXFR(251),
/** Transfer of an entire zone */
AXFR(252),
/** Mailbox-related RRs (MB, MG or MR) */
MAILB(253),
/** Mail Agent RRs (Obsolete - see MX) */
MAILA(254),
/** All types */
ALL(255),
/** DNSSEC Trust Authorities */
TA(32768),
/** DNSSEC Lookaside Validation */
DLV(32769);
Implemented response codes:
/** No error condition. */
NO_ERROR(0),
/**
* Format error.
*
* The name server was unable to interpret the query.
*/
FORMAT_ERROR(1),
/**
* Server failure.
*
* The name server was unable to process this query due to a problem with
* the name server.
*/
SERVER_FAILURE(2),
/**
* Name Error.
*
* Meaningful only for responses from an authoritative name server, this
* code signifies that the domain name referenced in the query does not exist.
*/
NAME_ERROR(3),
/**
* Not Implemented.
*
* The name server does not support the requested kind of query.
*/
NOT_IMPLEMENTED(4),
/**
* Refused.
*
* The name server refuses to perform the specified operation for policy
* reasons. For example, a name server may not wish to provide the
* information to the particular requester, or a name server may not wish to
* perform a particular operation (e.g., zone transfer) for particular data.
*/
REFUSED(5),
/** Name exists when it should not */
YX_DOMAIN(6),
/** RR Set Exists when it should not */
YXRR_SET(7),
/** RR Set that should exist does not */
NXRR_SET(8),
/** Server Not Authoritative for zone */
NOT_AUTHENTICATIVE(9),
/** Name not contained in zone */
NOT_IN_ZONE(10),
// 11-15 available for assignment
/** Bad OPT Version */
BAD_VERSION(16),
/** TSIG Signature Failure */
BAD_SIGNATURE(17),
/** Key not recognized */
BAD_KEY(18),
/** Signature out of time window */
BAD_TIME(19),
/** Bad TKEY Mode */
BAD_MODE(20),
/** Duplicate key name */
BAD_NAME(21),
/** Algorithm not supported */
BAD_ALGORITHM(22),
/** Bad Truncation */
BAD_TRUNCATION(23);
Record classes:
/** Reserved (IANA) */
RESERVED0(0),
/** The Internet */
IN(1),
/** The CSNET class (Obsolete - used only for examples in some obsolete RFCs) */
CS(2),
/** Zhe CHAOS class */
CH(3),
/** Hesiod [Dyer 87] */
HS(4),
/** None class */
NONE(254),
/** Any class */
ANY(255),
/** Reserved (IANA) */
RESERVED65535(65535);
Message opcodes:
/** Standard record */
STANDARD(0),
/** Inverse record */
INVERSE(1),
/** Status record */
STATUS(2),
/** Reserved (IANA) */
RESERVED3(3),
/** Notify */
NOTIFY(4),
/** Update */
UPDATE(5);
// 6-15 available for assignment
If you are interested in testing out the current code, just contact me. I’ll keep you informed :-).
Leave a Reply