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

You are writing a proxy DNS server.  A query comes in - potentially
answering it hits more than one remote DNS server;  responses will arrive
asynchronously on different threads, and you plug them into the DnsResponse
object as they arrive, counting down so that the last one in flushes it.

Yes, you could do some kind of internal data structure and create a
response just before flushing it, but a DnsResponse happens to *be* the
data structure you'd need...


On Mon, Nov 17, 2014 at 5:06 AM, Norman Maurer <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>();
>
> why must this be thread-safe ? all our pojos are not
>
> —
> Reply to this email directly or view it on GitHub
> <https://github.com/netty/netty/pull/3146/files#r20425652>.
>



-- 
http://timboudreau.com