DNS::HostMap DNS::resolve( const std::string& service, const std::string& proto, const std::string& domain, const LogSink& logInstance ) { logInstance.warn( LogAreaClassDns, "notice: gloox does not support SRV " "records on this platform. Using A records instead." ); return defaultHostMap( domain, logInstance ); }
DNS::HostMap DNS::resolve( const std::string& service, const std::string& proto, const std::string& domain, const LogSink& logInstance ) { const std::string dname = "_" + service + "._" + proto + "." + domain; bool error = false; DNS::HostMap servers; DNS_RECORD* pRecord; if( DnsQuery( dname.c_str(), DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, &pRecord, NULL ) == ERROR_SUCCESS ) { DNS_RECORD* pRec = pRecord; do { if( pRec->wType == DNS_TYPE_SRV ) { servers[pRec->Data.SRV.pNameTarget] = pRec->Data.SRV.wPort; } pRec = pRec->pNext; } while( pRec != NULL ); DnsRecordListFree( pRecord, DnsFreeRecordList ); } else error = true; if( error || !servers.size() ) { servers = defaultHostMap( domain, logInstance ); } return servers; }
DNS::HostMap DNS::resolve( const std::string& service, const std::string& proto, const std::string& domain, const LogSink& logInstance ) { const std::string dname = "_" + service + "._" + proto + "." + domain; bool error = false; DNS::HostMap servers; DNS_RECORD* pRecord = NULL; DNS_STATUS status = DnsQuery_UTF8( dname.c_str(), DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, &pRecord, NULL ); if( status == ERROR_SUCCESS ) { // NOTE: DnsQuery_UTF8 and DnsQuery_A really should have been defined with // PDNS_RECORDA instead of PDNS_RECORD, since that's what it is (even with _UNICODE defined). // We'll correct for that mistake with a cast. DNS_RECORDA* pRec = (DNS_RECORDA*)pRecord; do { if( pRec->wType == DNS_TYPE_SRV ) { servers[pRec->Data.SRV.pNameTarget] = pRec->Data.SRV.wPort; } pRec = pRec->pNext; } while( pRec != NULL ); DnsRecordListFree( pRecord, DnsFreeRecordList ); } else { logInstance.warn( LogAreaClassDns, "DnsQuery_UTF8() failed: " + util::int2string( status ) ); error = true; } if( error || !servers.size() ) { servers = defaultHostMap( domain, logInstance ); } return servers; }
DNS::HostMap DNS::resolve( const std::string& service, const std::string& proto, const std::string& domain, const LogSink& logInstance ) { buffer srvbuf; bool error = false; const std::string dname = "_" + service + "._" + proto; if( !domain.empty() ) srvbuf.len = res_querydomain( dname.c_str(), const_cast<char*>( domain.c_str() ), C_IN, T_SRV, srvbuf.buf, NS_PACKETSZ ); else srvbuf.len = res_query( dname.c_str(), C_IN, T_SRV, srvbuf.buf, NS_PACKETSZ ); if( srvbuf.len < 0 ) return defaultHostMap( domain, logInstance ); HEADER* hdr = (HEADER*)srvbuf.buf; unsigned char* here = srvbuf.buf + NS_HFIXEDSZ; if( ( hdr->tc ) || ( srvbuf.len < NS_HFIXEDSZ ) ) error = true; if( hdr->rcode >= 1 && hdr->rcode <= 5 ) error = true; if( ntohs( hdr->ancount ) == 0 ) error = true; if( ntohs( hdr->ancount ) > NS_PACKETSZ ) error = true; int cnt; for( cnt = ntohs( hdr->qdcount ); cnt>0; --cnt ) { int strlen = dn_skipname( here, srvbuf.buf + srvbuf.len ); here += strlen + NS_QFIXEDSZ; } unsigned char* srv[NS_PACKETSZ]; int srvnum = 0; for( cnt = ntohs( hdr->ancount ); cnt>0; --cnt ) { int strlen = dn_skipname( here, srvbuf.buf + srvbuf.len ); here += strlen; srv[srvnum++] = here; here += SRV_FIXEDSZ; here += dn_skipname( here, srvbuf.buf + srvbuf.len ); } if( error ) { return defaultHostMap( domain, logInstance ); } // (q)sort here HostMap servers; for( cnt=0; cnt<srvnum; ++cnt ) { name srvname; if( ns_name_ntop( srv[cnt] + SRV_SERVER, (char*)srvname, NS_MAXDNAME ) < 0 ) printf( "handle this error!\n" ); servers[(char*)srvname] = ns_get16( srv[cnt] + SRV_PORT ); } return servers; }
DNS::HostMap DNS::resolve( const std::string& service, const std::string& proto, const std::string& domain, const LogSink& logInstance ) { buffer srvbuf; bool error = false; const std::string dname = "_" + service + "._" + proto; if( !domain.empty() ) srvbuf.len = res_querydomain( dname.c_str(), const_cast<char*>( domain.c_str() ), C_IN, T_SRV, srvbuf.buf, NS_PACKETSZ ); else srvbuf.len = res_query( dname.c_str(), C_IN, T_SRV, srvbuf.buf, NS_PACKETSZ ); if( srvbuf.len < 0 ) return defaultHostMap( domain, logInstance ); HEADER* hdr = (HEADER*)srvbuf.buf; unsigned char* here = srvbuf.buf + NS_HFIXEDSZ; if( srvbuf.len < NS_HFIXEDSZ ) error = true; if( hdr->rcode >= 1 && hdr->rcode <= 5 ) error = true; if( ntohs( hdr->ancount ) == 0 ) error = true; if( ntohs( hdr->ancount ) > NS_PACKETSZ ) error = true; int cnt; for( cnt = ntohs( hdr->qdcount ); cnt > 0; --cnt ) { int strlen = dn_skipname( here, srvbuf.buf + srvbuf.len ); here += strlen + NS_QFIXEDSZ; } unsigned char* srv[NS_PACKETSZ]; int srvnum = 0; for( cnt = ntohs( hdr->ancount ); cnt > 0; --cnt ) { int strlen = dn_skipname( here, srvbuf.buf + srvbuf.len ); here += strlen; srv[srvnum++] = here; here += SRV_FIXEDSZ; here += dn_skipname( here, srvbuf.buf + srvbuf.len ); } if( error ) { return defaultHostMap( domain, logInstance ); } // (q)sort here HostMap servers; for( cnt = 0; cnt < srvnum; ++cnt ) { char srvname[NS_MAXDNAME]; srvname[0] = '\0'; if( dn_expand( srvbuf.buf, srvbuf.buf + NS_PACKETSZ, srv[cnt] + SRV_SERVER, srvname, NS_MAXDNAME ) < 0 || !(*srvname) ) continue; unsigned char* c = srv[cnt] + SRV_PORT; servers.insert( std::make_pair( (char*)srvname, ntohs( c[1] << 8 | c[0] ) ) ); } if( !servers.size() ) return defaultHostMap( domain, logInstance ); return servers; }