SOL9 2.0 Class: DnsRecordQueryT

 SOL9 C++ Class Library  SOL9 Samples  SOL9 Tutorial  SOL9 FAQ  SOL9 ClassTree 

Source code

/*
 * DnsRecordQueryT.h 
 * Copyright (c) 2011 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED. 
 */


// SOL9 2.0

// 2011/1/1 
// 2011/1/14 Updated
// 2011/1/18 Modified class name to be DnsRecordQueryT from DnsRecordListT

#pragma once
#include <sol/dns/DnsObject.h>
#include <sol/dns/IPv4AddressArray.h>
#include <sol/net/IPv4AddressInfoList.h>
#include <sol/dns/DnsRecordArrayT.h>
#include <sol/dns/DnsRecord.h>

/*
    Possible combinations of DNS query types and structures 
    -----------------------------------
        Structure           Type
    -----------------------------------
        DNS_A_DATA          DNS_TYPE_A
        DNS_SOA_DATA        DNS_TYPE_SOA

        DNS_PTR_DATA        DNS_TYPE_PTR
                            DNS_TYPE_NS
                            DNS_TYPE_CNAME
                            DNS_TYPE_DNAME
                            DNS_TYPE_MB
                            DNS_TYPE_MD
                            DNS_TYPE_MF
                            DNS_TYPE_MG
                            DNS_TYPE_MR

        DNS_MINFO_DATA      DNS_TYPE_MINFO
                            DNS_TYPE_RP

        DNS_MX_DATA         DNS_TYPE_MX
                            DNS_TYPE_AFSDB
                            DNS_TYPE_RT
        DNS_TXT_DATA        DNS_TYPE_HINFO
                            DNS_TYPE_ISDN
                            DNS_TYPE_TEXT
                            DNS_TYPE_X25

        DNS_NULL_DAT        DNS_TYPE_NULL
        DNS_WKS_DATA        DNS_TYPE_WKS
        DNS_AAAA_DAT        DNS_TYPE_AAAA
        DNS_KEY_DATA        DNS_TYPE_KEY
        DNS_SIG_DATA        DNS_TYPE_SIG
        DNS_ATMA_DATA       DNS_TYPE_ATMA
        DNS_NXT_DATA        DNS_TYPE_NXT
        DNS_SRV_DATA        DNS_TYPE_SRV
        DNS_NAPTR_DATA      DNS_TYPE_NAPTR
        DNS_TKEY_DATA       DNS_TYPE_TKEY
        DNS_TSIG_DATA       DNS_TYPE_TSIG
        DNS_WINS_DATA       DNS_TYPE_WINS
        DNS_WINSR_DATA      DNS_TYPE_WINSR
*/

namespace SOL {

template <class T> class DnsRecordQueryT :public DnsRecord {

private:
    WORD        type;

//private:
//    PDNS_RECORD pRecord;

private:
    IPv4AddressArray ipv4Array;

private:
    DnsRecordArrayT<T> recordArray;

public:
    /**
     * Constructor
     */
    DnsRecordQueryT(__in WORD qtype, __in const TCHAR* primaryDNSServer=NULL, 
            __in const TCHAR* secondaryDNSServer=NULL)
        :type(qtype)
    {
        //Check DNS query type
        if ((type >= DNS_TYPE_A     && type<=DNS_TYPE_OPT) ||
            (type >= DNS_TYPE_ADDRS && type<=DNS_TYPE_ANY) ||
            (type >=DNS_TYPE_WINS   && type<=DNS_TYPE_WINSR)) {        //2011/1/20 Added for Windows specific query types.
            ; //OK
        } else {
            throw Exception("DnsRecordQueryT::DnsRecordQueryT; Invalid type");
        }

        int count = 0;
        if (primaryDNSServer) {
            count++;
        }
        if (secondaryDNSServer) {
            count++;
        }

        if (count > 0) {
            ipv4Array.allocArray(count);
            int n = 0;
            if (primaryDNSServer) {
                try {
                    IPv4AddressInfoList infoList;
                    infoList.getAddrInfo(primaryDNSServer);
                    _tprintf(_T("primaryDNSServer %s\n"), primaryDNSServer);
                    in_addr addr;
                    infoList.getFirst(addr);
                    ipv4Array.setNth(n++, addr);
                } catch (...) {
                    ;//Ignore error
                    _tprintf(_T("Error in IPv4AddressInfoList::getAddrInfo() for %s\n"), primaryDNSServer);
                }
            }

            if (secondaryDNSServer) {
                try {
                    IPv4AddressInfoList infoList;

                    infoList.getAddrInfo(secondaryDNSServer);
                    _tprintf(_T("secondaryDNSServer %s\n"), secondaryDNSServer);

                    in_addr addr;
                    infoList.getFirst(addr);
                    ipv4Array.setNth(n++, addr);
                } catch (...) {
                    ;//Ignore error
                    _tprintf(_T("Error in IPv4AddressInfoList::getAddrInfo() for %s\n"), secondaryDNSServer);

                }
            }
            //Reconfirm the values forIP4_ARRAY 
            ipv4Array.display();
        }
    }

public:
    /**
     *
     */
    ~DnsRecordQueryT()
    {
        clear();
    }

public:
    void clear()
    {
        recordArray.clear();
        DNS_RECORD* pRecord = getRecord();
        if (pRecord) {
            DnsRecordListFree(pRecord, DnsFreeRecordList);
        }
    }

public:
    /**
     * Call DnsQuery API and store the result to DNSRecordArrayT recordArray 
     */
    int query(__in const TCHAR* hostDomain, __in DWORD options=DNS_QUERY_STANDARD)
    {
        clear();

        size_t count = 0;
        DNS_RECORD* pRecord = NULL;

        DWORD rc =     DnsQuery(hostDomain, 
                        this->type,                //DNS_TYPE_ANY,
                        options,
                        (void*)(const IP4_ARRAY*)ipv4Array,    //NULL, 
                        &pRecord, NULL);

        if (rc != ERROR_SUCCESS) {
            throw Exception("DnsRecordQueryT::query failed", rc);
        } else {

            setRecord(pRecord);

            PDNS_RECORD ptr = pRecord;
            while (ptr) {
                if(ptr->wType == this->type) {
                    count++;
                }
                ptr = ptr->pNext;
            }

            if (count >0) {
                //Allocate DNSRecordArrayT recordArray of count. 
                DnsRecordT<T>* tarray = this->recordArray.alloc(type, count);

                int n = 0;    
                PDNS_RECORD ptr = pRecord;
                while (ptr) {
                    if(ptr->wType == this->type) {
                        T* data = (T*)&(ptr->Data);
                        if (data) {
                            //Make a copy for data to tarray 
                            tarray->copy(ptr->pName, ptr->wType, ptr->dwTtl, ptr->Flags.S, ptr->wDataLength, *data);
                            tarray++;
                        }
                    }
                    ptr = ptr->pNext;
                }
            }
        } 
        return count;
    }

public:
    void getFirst(T& t) 
    {
        getNth(0, t);
    }

public:
    void getNth(int n, T& t) 
    {
        DnsRecordT<T>& record = recordArray.getNth(n);
        t = record.getData();
    }

public:
    T& getFirst() 
    {
        return getNth(0);
    }

public:
    T& getNth(int n) 
    {
        DnsRecordT<T>& record = recordArray.getNth(n);
        return record.getData();
    }

public:
    bool getNth(int n, DnsRecordT<T>& record) 
    {
        bool rc = true;
        record = recordArray.getNth(n);
        return rc;
    }

public:
    void display()
    {
        recordArray.display();
    }

};

}

Last modified: 1 Feb 2012

Copyright (c) 2009-2012 Antillia.com ALL RIGHTS RESERVED.