Do the actual DNS query.

Return TypeFunction nameArguments
hzEcodehzDNS::Query(const char*,DnsType,)

Declared in file: hzDNS.h
Defined in file : hzDNS.cpp

Function Logic:

0:START 1:items 2:unknown 3:Return hzerr(E_ARGUMENT,No domain name supplied) 4:unknown 5:m_cpDns 6:ix 7:unknown 8:items 9:unknown 10:unknown 11:Return hzerr(E_INITFAIL,Could not init DNS resolver) 12:s_bInitResolver 13:items pLog nSize 14:unknown 15:Return hzerr(E_OVERFLOW,DNS buffer overflow for %s,dom) 16:unknown 17:h_errno 18:HOST_NOT_FOUND 19:Return E_DNS_NOHOST 20:NO_DATA 21:Return E_DNS_NODATA 22:NO_RECOVERY 23:Return E_DNS_FAILED 24:TRY_AGAIN 25:Return E_DNS_RETRY 26:Return hzerr(E_DNS_FAILED,Unspecified error (%s) for domain %s,hstrerror(h_errno),dom) 27:m_cpDns 28:unknown 29:items 30:unknown 31:unknown 32:items 33:items 34:items 35:unknown 36:items 37:items 38:unknown 39:items 40:items ( 41:m_qID ( m_DNA ( nQus ( nAns ( nAut ( nAdd 42:unknown 43:items items items items items items 44:unknown 45:ix 46:unknown 47:items dr 48:unknown 49:items 50:Return hzerr(E_DNS_FAILED,Answer record without domain) 51:unknown 52:items ( 53:dr ( dr ( ( ( dr ( dr dr ix ix jx 54:unknown 55:items 56:unknown 57:( 58:dr ix 59:unknown 60:items 61:unknown 62:items 63:unknown 64:items 65:dr.m_nType==DNSTYPE_AAAA 66:( 67:( 68:( 69:dr ( ( ( dr ( ( ( dr ( ( ( dr 70:unknown 71:items 72:unknown 73:items 74:dr 75:unknown 76:items 77:Return hzerr(E_DNS_FAILED,Answer record without server) 78:items ix 79:unknown 80:items dr 81:unknown 82:items 83:Return hzerr(E_DNS_FAILED,Authority record without domain) 84:unknown 85:items ( 86:dr ( dr ( ( ( dr ( dr dr ix ix jx 87:unknown 88:items 89:unknown 90:( 91:dr ix 92:unknown 93:items 94:dr.m_nType==DNSTYPE_AAAA 95:( 96:( 97:( 98:dr ( ( ( dr ( ( ( dr ( ( ( dr ix 99:dr 100:unknown 101:items 102:Return hzerr(E_DNS_FAILED,Authority record without server) 103:items ix 104:Return E_OK

Function body:

hzEcode hzDNS::Query (const char* dom)DnsType eType, 
{
   //  Do the actual DNS query.
   //  
   //  Arguments: 1) eType Query type Either MX or A
   //     2) dom  Domain name
   //  
   //  Returns: E_ARGUMENT  If the domain name is not supplied
   //     E_INITFAIL  If res_init() has not been called before and now returns an error
   //     E_OVERFLOW  If the res_search function owverfills the buffer
   //     E_DNS_NOHOST If the host does not exist
   //     E_DNS_NODATA If the domain exists but there is no host for the applicable service
   //     E_DNS_RETRY  If the DNS could not provide data at this time
   //     E_DNS_FAILED If the DNS failed
   //     E_OK   If the DNS query was successful
   _hzfunc("hzDNS::Query") ;
   hzChain     errCh ;     //  In the event of error, shows progress so far 
   DnsRec      dr ;        //  DNS record
   hzLogger*   pLog ;      //  For debug mode
   uchar*      ix ;        //  DNS record iterator
   uchar*      jx ;        //  DNS record forward marker
   uint32_t    nQus ;      //  Questions
   uint32_t    nAns ;      //  Questions
   uint32_t    nAut ;      //  Questions
   uint32_t    nAdd ;      //  Questions
   uint32_t    nCount ;    //  Interator res_search response
   int32_t     nSize ;     //  Bytes returned by res_search
   //  Clear m_Error
   m_Error.Clear() ;
   //  Check args
   if (!dom || !dom[0])
       return hzerr(E_ARGUMENT, "No domain name supplied") ;
   //  Check buffer
   if (!m_cpDns)
       m_cpDns = new uchar[2048];
   ix = m_cpDns ;
   if (!ix)
       hzexit(E_MEMORY, "Could not allocate buffers for DNS query") ;
   //  Chekck res_init() has been called (only once)
   if (!s_bInitResolver)
   {
       if (res_init() == -1)
           return hzerr(E_INITFAIL, "Could not init DNS resolver") ;
       s_bInitResolver = true ;
   }
   _clear() ;
   pLog = GetThreadLogger() ;
   /*
   **  ** Query the DNS
   **      */
   nSize = res_search(dom, C_IN, eType, m_cpDns, 2047);
   if (nSize >&eq; 2000)
       return hzerr(E_OVERFLOW, "DNS buffer overflow for %s", dom) ;
   if (nSize == -1)
   {
       switch (h_errno)
       {
       case HOST_NOT_FOUND:    return E_DNS_NOHOST ;   //  The specified host is unknown.
       case NO_DATA:           return E_DNS_NODATA ;   //  The requested name is valid but does not have an IP address.
       case NO_RECOVERY:       return E_DNS_FAILED ;   //  A non-recoverable name server error occurred.
       case TRY_AGAIN:         return E_DNS_RETRY ;    //  A temporary error occurred on an authoritative name server. Try again later.
       }
       return hzerr(E_DNS_FAILED, "Unspecified error (%s) for domain %s", hstrerror(h_errno), dom) ;
   }
   m_cpDns[nSize] = 0;
   if (_hzGlobal_Debug & HZ_DEBUG_DNS)
   {
       errCh.Printf("DNS BUFFER (%d bytes) =\n[\n", nSize) ;
       for (nCount = 0; nCount < (uint32_t) nSize ;)
       {
           if (nCount < 240&&m_cpDns[nCount]> 32&&m_cpDns[nCount] < 128)
               errCh.Printf("  %c", m_cpDns[nCount]) ;
           else
               errCh.Printf(" %02x", m_cpDns[nCount]) ;
           nCount++ ;
           if (!(nCount % 40))
               errCh.AddByte(CHAR_NL) ;
           else
               errCh.AddByte(CHAR_SPACE) ;
       }
       if (nCount % 40)
           errCh.AddByte(CHAR_NL) ;
       errCh.Printf("]\n") ;
   }
   //  Get result params
   m_qID =  (m_cpDns[0] << 8)+ m_cpDns[1];
   m_DNA =  (m_cpDns[2] << 8)+ m_cpDns[3];
   nQus = (m_cpDns[4] << 8)+ m_cpDns[5];
   nAns = (m_cpDns[6] << 8)+ m_cpDns[7];
   nAut = (m_cpDns[8] << 8)+ m_cpDns[9];
   nAdd = (m_cpDns[10]<<8)+ m_cpDns[11];
   if (_hzGlobal_Debug & HZ_DEBUG_DNS)
   {
       errCh.Printf("Query id:      %d\n", m_qID) ;
       errCh.Printf("DNA code:      %d\n", m_DNA) ;
       errCh.Printf("No questions:  %d\n", nQus) ;
       errCh.Printf("No answers:    %d\n", nAns) ;
       errCh.Printf("No authority:  %d\n", nAut) ;
       errCh.Printf("No additional: %d\n", nAdd) ;
   }
   /*
   **  ** Bypass the 'pre-defined' strings to get the answers
   **      */
   for (ix = m_cpDns + 12;*ix ; ix++) ;
   ix += 5;
   //  Now have answers
   for (nCount = 0; nCount < nAns ; nCount++)
   {
       dr.Clear() ;
       dr.m_Domain = _procraw(&ix) ;
       if (!dr.m_Domain)
       {
           pLog->Out(errCh) ;
           return hzerr(E_DNS_FAILED, "Answer record without domain") ;
       }
       if (_hzGlobal_Debug & HZ_DEBUG_DNS)
           errCh.Printf("Answ: %s:", *dr.m_Domain) ;
       dr.m_nType =  (ix[0]<<  8)+ ix[1];
       dr.m_nClass = (ix[2]<<  8)+ ix[3];
       dr.m_nTTL =   (ix[4]<< 24)+(ix[5]<< 16)+(ix[6]<< 8)+ ix[7];
       dr.m_nLen =   (ix[8]<<  8)+ ix[9];
       dr.m_nValue = 0;
       ix += 10;
       jx = ix + dr.m_nLen ;
       if (_hzGlobal_Debug & HZ_DEBUG_DNS)
           errCh.Printf(" -> Type %u Class %u TTL %u Len %u", dr.m_nType, dr.m_nClass, dr.m_nTTL, dr.m_nLen) ;
       if (dr.m_nType == DNSTYPE_MX)
       {
           dr.m_nValue = (ix[0]<< 8)+ ix[1];
           ix += 2;
           if (_hzGlobal_Debug & HZ_DEBUG_DNS)
               errCh.Printf(" Val %u", dr.m_nValue) ;
       }
       if (dr.m_nType == DNSTYPE_A)
       {
           dr.m_Ipa.SetValue(ix[0],ix[1],ix[2],ix[3]);
           if (_hzGlobal_Debug & HZ_DEBUG_DNS)
               errCh.Printf(" IPv4 (%u.%u.%u.%u)\n", ix[0],ix[1],ix[2],ix[3]);
       }
       else if (dr.m_nType == DNSTYPE_AAAA)
       {
           dr.m_anorakA = (ix[0] << 24)+(ix[1] << 16)+(ix[2] << 8)+ (ix[3]);
           dr.m_anorakB = (ix[4] << 24)+(ix[5] << 16)+(ix[6] << 8)+ (ix[7]);
           dr.m_anorakC = (ix[8] << 24)+(ix[9] << 16)+(ix[10]<<8)+ (ix[11]);
           dr.m_anorakD = (ix[12]<<24)+(ix[13]<<16)+(ix[14]<<8)+ (ix[15]);
           if (_hzGlobal_Debug & HZ_DEBUG_DNS)
               errCh.Printf(" IPv6 (%u.%u.%u.%u)\n", dr.m_anorakA, dr.m_anorakB, dr.m_anorakC, dr.m_anorakD) ;
       }
       else
       {
           if (_hzGlobal_Debug & HZ_DEBUG_DNS)
               errCh.AddByte(CHAR_NL) ;
           dr.m_Server = _procraw(&ix) ;
           if (!dr.m_Server)
           {
               pLog->Out(errCh) ;
               return hzerr(E_DNS_FAILED, "Answer record without server") ;
           }
       }
       m_arAns.Add(dr) ;
       ix = jx ;
   }
   //  Get authority records
   for (nCount = 0; nCount < nAut ; nCount++)
   {
       dr.Clear() ;
       //  Get the domain name
       dr.m_Domain = _procraw(&ix) ;
       if (!dr.m_Domain)
       {
           pLog->Out(errCh) ;
           return hzerr(E_DNS_FAILED, "Authority record without domain") ;
       }
       if (_hzGlobal_Debug & HZ_DEBUG_DNS)
           errCh.Printf("Auth: %s:", *dr.m_Domain) ;
       dr.m_nType =  (ix[0]<<  8)+ ix[1];
       dr.m_nClass = (ix[2]<<  8)+ ix[3];
       dr.m_nTTL =   (ix[4]<< 24)+(ix[5]<< 16)+(ix[6]<< 8)+ ix[7];
       dr.m_nLen =   (ix[8]<<  8)+ ix[9];
       dr.m_nValue = 0;
       ix += 10;
       jx = ix + dr.m_nLen ;
       if (_hzGlobal_Debug & HZ_DEBUG_DNS)
           errCh.Printf(" -> Type %u Class %u TTL %u Len %u\n", dr.m_nType, dr.m_nClass, dr.m_nTTL, dr.m_nLen) ;
       if (dr.m_nType == DNSTYPE_MX)
           { dr.m_nValue = (ix[0]<< 8)+ ix[1]; ix += 2; }
       if (dr.m_nType == DNSTYPE_A)
           dr.m_Ipa.SetValue(ix[0],ix[1],ix[2],ix[3]);
       else if (dr.m_nType == DNSTYPE_AAAA)
       {
           dr.m_anorakA = (ix[0] << 24)+(ix[1] << 16)+(ix[2] << 8)+ (ix[3]);
           dr.m_anorakA = (ix[4] << 24)+(ix[5] << 16)+(ix[6] << 8)+ (ix[7]);
           dr.m_anorakA = (ix[8] << 24)+(ix[9] << 16)+(ix[10]<<8)+ (ix[11]);
           dr.m_anorakA = (ix[12]<<24)+(ix[13]<<16)+(ix[14]<<8)+ (ix[15]);
           ix += 16;
       }
       else
       {
           dr.m_Server = _procraw(&ix) ;
           if (!dr.m_Server)
           {
               pLog->Out(errCh) ;
               return hzerr(E_DNS_FAILED, "Authority record without server") ;
           }
       }
       m_arAut.Add(dr) ;
       ix = jx ;
   }
   return E_OK ;
}