/*---------------------------------------------------------------------------*/
/* dns_cache.h                                                               */
/* copyright (c) innovaphone 2011                                            */
/* DNS caching                                                               */
/*---------------------------------------------------------------------------*/

NAMESPACE_BEGIN

/*---------------------------------------------------------------------------*/
/* class DnsCache                                                            */
/*---------------------------------------------------------------------------*/

enum DnsQueryType {
    UNKNOWN_QTYPE = 0,
    QTYPE_A = 1,        /* a host address */
    QTYPE_NS = 2,       /* an authoritative name server */
    QTYPE_CNAME = 5,    /* canonical name for an alias */
    QTYPE_SOA = 6,      /* start of a zone of authority */
    QTYPE_PTR = 12,     /* domain name pointer */
    QTYPE_MX = 15,      /* mail exchange */
    QTYPE_TXT = 16,     /* text strings */
    QTYPE_AAAA = 28,    /* an IPv6 host address */
    QTYPE_SRV = 33,     /* server records RFC 2782 */
    QTYPE_NAPTR = 35,   /* naming authority pointer, RFC 2915 */
};

/* some RFC error codes
 */
#define DNS_RES_SUCCESS         0
#define DNS_RES_FORMAT_ERR      1
#define DNS_RES_SERVER_FAILURE  2
#define DNS_RES_NXDOMAIN        3
#define DNS_RES_NOT_IMPLEMENTED 4
#define DNS_RES_REFUSED         5

/* private error codes
 */
#define DNS_RES_TIMEOUT         16
#define DNS_RES_LOCAL_ERR       17
#define DNS_RES_NO_RESULT       18
#define DNS_RES_CACHE_MISS      19
#define DNS_RES_CACHE_UNRELATED 20

#define DNS_CACHE_FLAG_UNSUITABLE  0x0001
#define DNS_CACHE_FLAG_LAST_USED   0x0002
#define DNS_CACHE_FLAG_STATIC      0x0004

#define DNS_CACHE_TTL_PERSIST ((dword)-1)

#define DNS_CACHE_LOOKUP_FLAG_ALL  0x00000001
#define DNS_CACHE_LOOKUP_NO_IPV6   0x00000002
#define DNS_CACHE_LOOKUP_ITERATE   0x00000004
#define DNS_CACHE_LOOKUP_ONLY_IPV6 0x00000008

const char *DnsQueryTypeName(DnsQueryType qtype);

class DnsCacheResult {
public:
    virtual ~DnsCacheResult() {}
    virtual const char *qname() = 0;
    virtual unsigned ttl() = 0;
    virtual unsigned Print(char *buf, unsigned sz) = 0;

    class DnsCacheResult * resultNext;
    word resultFlags;
    byte precedence;
    DnsQueryType qtype;
    word rcode;

    union {
        struct {
            IPaddr addr;
        } a;
        struct {
            IPaddr addr;
        } aaaa;
    } u;
};

class IDnsCache {
public:
    static IDnsCache * Create();
    virtual ~IDnsCache();

    virtual void UpdateA(const char * qname, dword ttl, word servicePort, word rcode, IPaddr addr) = 0;
    virtual void UpdateAAAA(const char * qname, dword ttl, word servicePort, word rcode, IPaddr addr) = 0;
    virtual void LastUsedAddr(const char * qname, IPaddr addr, word servicePort) = 0;
    virtual bool UnsuitableAddr(const char * qname, IPaddr addr, word servicePort) = 0;
    virtual void ClearUnsuitableAddrs(const char * qname, word servicePort) = 0;
    virtual word LookupA(const char * qname, word servicePort, DnsCacheResult ***answerRRs) = 0;
    virtual word LookupAAAA(const char * qname, word servicePort, DnsCacheResult ***answerRRs) = 0;
    virtual word Lookup(const char * qname, dword flags, word servicePort, const char * serviceName, DnsCacheResult **answerRRs) = 0;
    virtual void SortResults(DnsCacheResult **results) = 0;
    virtual void List(DnsCacheResult **answerRRs) = 0;
    virtual void ListStatic(DnsCacheResult **answerRRs) = 0;
    virtual void Clear() = 0;
    virtual void ClearStatic() = 0;
    virtual void InvalidateQname(const char * qname) = 0;
    virtual void Invalidate() = 0;
    virtual void ExpireEntries() = 0;
};

NAMESPACE_END
