DNS server support

Support for writing DNS servers, and various API changes to accomplish that, specifically:

 - `DnsType` -> `DnsType<RecordType>` where RecordType is a subclass of `DnsEntry`, and has payload decoders for specific types
 - Introduced record-specific subclasses of `DnsEntry` for common types, with fallback to the ByteBuf-based `DnsResource`
 - `DnsEntry` gains public `writeTo()` and `writePayload()` to write itself correctly into a ByteBuf
 - Added `DnsQueryDecoder` and `DnsResponseEncoder`
 - Introduced `NameWriter` for writing names, so that it's possible to implement a stateful `NameWriter` to do DNS name compression
 - `DnsMessage` is threadsafe (needed for proxy DNS servers where multiple calls to remote DNS servers may contribute partial responses)
    - If someone really feels strongly that creating the `List` instances it uses internally should be lazy, that could be done, but it would be good to have some evidence that really accomplishes something - feels like premature optimization
 - `DnsQuestion` is no longer a subclass of `DnsEntry` (which now has a time-to-live, since that is common to all other record types).
 - Added the package io.netty.handler.codec.dns.server with `DnsServerHandler`, a `SimpleChannelInboundHandler<DatagramPacket>` that handles the common plumbing of writing a DNS server that is unlikely to differ between implementations
 - Corrected error codes in `DnsResponseCode` to match https://tools.ietf.org/html/rfc2929 (they were sequential, but in fact 11-15 are unused and numbering restarts at 16)
 - Added error codes that exist but were not included in `DnsResponseCode` but are part of the spec
 - Added `DnsDecoderException` which can specify a `DnsResponseCode`
 - `DnsQuery` implements `Iterable<DnsQuestion>`, simply because it's intuitive
 - Reasonable `toString()` implementations on entity classes for logging purposes
 - Added to netty-examples:  DNS server, DNS client, proxy DNS server

Okay, I've reverted the changes to make it thread-safe - I'll deal with
that some other way.  I don't think the interface approach would help much,
since we'd need a bunch more interfaces to make it all useful.

On Mon, Nov 17, 2014 at 8:19 AM, Trustin Lee <notifications@github.com>
wrote:

> In codec-dns/src/main/java/io/netty/handler/codec/dns/DnsMessage.java:
>
> > @@ -28,10 +29,10 @@
> >   */
> >  public abstract class DnsMessage extends AbstractReferenceCounted {
> >
> > -    private List<DnsQuestion> questions;
> > -    private List<DnsResource> answers;
> > -    private List<DnsResource> authority;
> > -    private List<DnsResource> additional;
> > +    private final List<DnsQuestion> questions = new CopyOnWriteArrayList<DnsQuestion>();
> > +    private final List<DnsEntry> answers = new CopyOnWriteArrayList<DnsEntry>();
> > +    private final List<DnsEntry> authority = new CopyOnWriteArrayList<DnsEntry>();
> > +    private final List<DnsEntry> additional = new CopyOnWriteArrayList<DnsEntry>();
>
> How about making DnsMessage an interace? You could implement a
> thread-safe DnsMessage implementation for your DNS server.
>
> On the other hand, you could perform the remote queries in the same event
> loop to avoid all the context switches and concurrent modifications.
>
> Another thing to note is this change increases the number of instantiated
> objects per DnsMessage. Before this change, unused lists are not
> instantiated at all.
>
> —
> Reply to this email directly or view it on GitHub
> <https://github.com/netty/netty/pull/3146/files#r20434276>.
>



-- 
http://timboudreau.com