/****************************************************************************** * DnsQuery_A [DNSAPI.@] * */ DNS_STATUS WINAPI DnsQuery_A( PCSTR name, WORD type, DWORD options, PVOID servers, PDNS_RECORDA *result, PVOID *reserved ) { WCHAR *nameW; DNS_RECORDW *resultW; DNS_STATUS status; TRACE( "(%s,%s,0x%08x,%p,%p,%p)\n", debugstr_a(name), dns_type_to_str( type ), options, servers, result, reserved ); if (!name || !result) return ERROR_INVALID_PARAMETER; nameW = dns_strdup_aw( name ); if (!nameW) return ERROR_NOT_ENOUGH_MEMORY; status = DnsQuery_W( nameW, type, options, servers, &resultW, reserved ); if (status == ERROR_SUCCESS) { *result = (DNS_RECORDA *)DnsRecordSetCopyEx( (DNS_RECORD *)resultW, DnsCharSetUnicode, DnsCharSetAnsi ); if (!*result) status = ERROR_NOT_ENOUGH_MEMORY; DnsRecordListFree( (DNS_RECORD *)resultW, DnsFreeRecordList ); } dns_free( nameW ); return status; }
QT_BEGIN_NAMESPACE void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, const QHostAddress &nameserver, QDnsLookupReply *reply) { // Perform DNS query. PDNS_RECORD dns_records = 0; const QString requestNameUtf16 = QString::fromUtf8(requestName.data(), requestName.size()); IP4_ARRAY srvList; memset(&srvList, 0, sizeof(IP4_ARRAY)); if (!nameserver.isNull()) { if (nameserver.protocol() == QAbstractSocket::IPv4Protocol) { // The below code is referenced from: http://support.microsoft.com/kb/831226 srvList.AddrCount = 1; srvList.AddrArray[0] = htonl(nameserver.toIPv4Address()); } else if (nameserver.protocol() == QAbstractSocket::IPv6Protocol) { // For supoprting IPv6 nameserver addresses, we'll need to switch // from DnsQuey() to DnsQueryEx() as it supports passing an IPv6 // address in the nameserver list qWarning() << Q_FUNC_INFO << "IPv6 addresses for nameservers is currently not supported"; reply->error = QDnsLookup::ResolverError; reply->errorString = tr("IPv6 addresses for nameservers is currently not supported"); return; } } const DNS_STATUS status = DnsQuery_W(reinterpret_cast<const wchar_t*>(requestNameUtf16.utf16()), requestType, DNS_QUERY_STANDARD, &srvList, &dns_records, NULL); switch (status) { case ERROR_SUCCESS: break; case DNS_ERROR_RCODE_FORMAT_ERROR: reply->error = QDnsLookup::InvalidRequestError; reply->errorString = tr("Server could not process query"); return; case DNS_ERROR_RCODE_SERVER_FAILURE: reply->error = QDnsLookup::ServerFailureError; reply->errorString = tr("Server failure"); return; case DNS_ERROR_RCODE_NAME_ERROR: reply->error = QDnsLookup::NotFoundError; reply->errorString = tr("Non existent domain"); return; case DNS_ERROR_RCODE_REFUSED: reply->error = QDnsLookup::ServerRefusedError; reply->errorString = tr("Server refused to answer"); return; default: reply->error = QDnsLookup::InvalidReplyError; reply->errorString = QSystemError(status, QSystemError::NativeError).toString(); return; } // Extract results. for (PDNS_RECORD ptr = dns_records; ptr != NULL; ptr = ptr->pNext) { const QString name = QUrl::fromAce( QString::fromWCharArray( ptr->pName ).toLatin1() ); if (ptr->wType == QDnsLookup::A) { QDnsHostAddressRecord record; record.d->name = name; record.d->timeToLive = ptr->dwTtl; record.d->value = QHostAddress(ntohl(ptr->Data.A.IpAddress)); reply->hostAddressRecords.append(record); } else if (ptr->wType == QDnsLookup::AAAA) { Q_IPV6ADDR addr; memcpy(&addr, &ptr->Data.AAAA.Ip6Address, sizeof(Q_IPV6ADDR)); QDnsHostAddressRecord record; record.d->name = name; record.d->timeToLive = ptr->dwTtl; record.d->value = QHostAddress(addr); reply->hostAddressRecords.append(record); } else if (ptr->wType == QDnsLookup::CNAME) { QDnsDomainNameRecord record; record.d->name = name; record.d->timeToLive = ptr->dwTtl; record.d->value = QUrl::fromAce(QString::fromWCharArray(ptr->Data.Cname.pNameHost).toLatin1()); reply->canonicalNameRecords.append(record); } else if (ptr->wType == QDnsLookup::MX) { QDnsMailExchangeRecord record; record.d->name = name; record.d->exchange = QUrl::fromAce(QString::fromWCharArray(ptr->Data.Mx.pNameExchange).toLatin1()); record.d->preference = ptr->Data.Mx.wPreference; record.d->timeToLive = ptr->dwTtl; reply->mailExchangeRecords.append(record); } else if (ptr->wType == QDnsLookup::NS) { QDnsDomainNameRecord record; record.d->name = name; record.d->timeToLive = ptr->dwTtl; record.d->value = QUrl::fromAce(QString::fromWCharArray(ptr->Data.Ns.pNameHost).toLatin1()); reply->nameServerRecords.append(record); } else if (ptr->wType == QDnsLookup::PTR) { QDnsDomainNameRecord record; record.d->name = name; record.d->timeToLive = ptr->dwTtl; record.d->value = QUrl::fromAce(QString::fromWCharArray(ptr->Data.Ptr.pNameHost).toLatin1()); reply->pointerRecords.append(record); } else if (ptr->wType == QDnsLookup::SRV) { QDnsServiceRecord record; record.d->name = name; record.d->target = QUrl::fromAce(QString::fromWCharArray(ptr->Data.Srv.pNameTarget).toLatin1()); record.d->port = ptr->Data.Srv.wPort; record.d->priority = ptr->Data.Srv.wPriority; record.d->timeToLive = ptr->dwTtl; record.d->weight = ptr->Data.Srv.wWeight; reply->serviceRecords.append(record); } else if (ptr->wType == QDnsLookup::TXT) { QDnsTextRecord record; record.d->name = name; record.d->timeToLive = ptr->dwTtl; for (unsigned int i = 0; i < ptr->Data.Txt.dwStringCount; ++i) { record.d->values << QString::fromWCharArray((ptr->Data.Txt.pStringArray[i])).toLatin1();; } reply->textRecords.append(record); } } DnsRecordListFree(dns_records, DnsFreeRecordList); }
PDNS_BLOB WINAPI SaBlob_Query(IN LPWSTR Name, IN WORD DnsType, IN ULONG Flags, IN PVOID *Reserved, IN DWORD AddressFamily) { PDNS_RECORD DnsRecord = NULL; INT ErrorCode; PDNS_BLOB DnsBlob = NULL; LPWSTR LocalName, LocalNameCopy; /* If they want reserved data back, clear it out in case we fail */ if (Reserved) *Reserved = NULL; /* Query DNS */ ErrorCode = DnsQuery_W(Name, DnsType, Flags, NULL, &DnsRecord, Reserved); if (ErrorCode != ERROR_SUCCESS) { /* We failed... did the caller use reserved data? */ if (Reserved && *Reserved) { /* He did, and it was valid. Free it */ DnsApiFree(*Reserved); *Reserved = NULL; } /* Normalize error code */ if (ErrorCode == RPC_S_SERVER_UNAVAILABLE) ErrorCode = WSATRY_AGAIN; goto Quickie; } /* Now create the Blob from the DNS Records */ DnsBlob = SaBlob_CreateFromRecords(DnsRecord, TRUE, DnsType); if (!DnsBlob) { /* Failed, get error code */ ErrorCode = GetLastError(); goto Quickie; } /* Make sure it has a name */ if (!DnsBlob->Name) { /* It doesn't, fail */ ErrorCode = DNS_INFO_NO_RECORDS; goto Quickie; } /* Check if the name is local or loopback */ if (!(DnsNameCompare_W(DnsBlob->Name, L"localhost")) && !(DnsNameCompare_W(DnsBlob->Name, L"loopback"))) { /* Nothing left to do, exit! */ goto Quickie; } /* This is a local name...query it */ LocalName = DnsQueryConfigAllocEx(DnsConfigFullHostName_W, NULL, NULL); if (LocalName) { /* Create a copy for the caller */ LocalNameCopy = Dns_CreateStringCopy_W(LocalName); if (LocalNameCopy) { /* Overwrite the one in the blob */ DnsBlob->Name = LocalNameCopy; } else { /* We failed to make a copy, free memory */ DnsApiFree(LocalName); } } Quickie: /* Free the DNS Record if we have one */ if (DnsRecord) DnsRecordListFree(DnsRecord, DnsFreeRecordList); /* Check if this is a failure path with an active blob */ if ((ErrorCode != ERROR_SUCCESS) && (DnsBlob)) { /* Free the blob */ SaBlob_Free(DnsBlob); DnsBlob = NULL; } /* Set the last error and return */ SetLastError(ErrorCode); return DnsBlob; }
int getAFSServerW(const cm_unichar_t *service, const cm_unichar_t *protocol, const cm_unichar_t *cellName, unsigned short afsdbPort, /* network byte order */ int *cellHostAddrs, cm_unichar_t cellHostNames[][MAXHOSTCHARS], unsigned short ports[], /* network byte order */ unsigned short ipRanks[], int *numServers, int *ttl) { #ifdef DNSAPI_ENV PDNS_RECORDW pDnsCell, pDnsIter, pDnsVol,pDnsVolIter, pDnsCIter; int i; cm_unichar_t query[1024]; *numServers = 0; *ttl = 0; if (service == NULL || protocol == NULL || cellName == NULL) return -1; #ifdef AFS_FREELANCE_CLIENT if ( cm_stricmp_utf16(cellName, L"Freelance.Local.Root") == 0 ) return -1; #endif /* AFS_FREELANCE_CLIENT */ /* query the SRV _afs3-vlserver._udp records of cell */ StringCbPrintfW(query, sizeof(query), L"_%S._%S.%S", service, protocol, cellName); if (query[wcslen(query)-1] != L'.') { StringCbCatW(query, sizeof(query), L"."); } if (DnsQuery_W(query, DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, (PDNS_RECORD *) &pDnsCell, NULL) == ERROR_SUCCESS) { /* go through the returned records */ for (pDnsIter = pDnsCell; pDnsIter; pDnsIter = pDnsIter->pNext) { /* if we find an SRV record, we found a service instance */ if (pDnsIter->wType == DNS_TYPE_SRV) { StringCbCopyW(cellHostNames[*numServers], sizeof(cellHostNames[*numServers]), pDnsIter->Data.SRV.pNameTarget); ipRanks[*numServers] = pDnsIter->Data.SRV.wPriority; ports[*numServers] = htons(pDnsIter->Data.SRV.wPort); (*numServers)++; if (!*ttl) *ttl = pDnsIter->dwTtl; if (*numServers == AFSMAXCELLHOSTS) break; } } for (i=0;i<*numServers;i++) cellHostAddrs[i] = 0; /* now check if there are any A records in the results */ for (pDnsIter = pDnsCell; pDnsIter; pDnsIter = pDnsIter->pNext) { if(pDnsIter->wType == DNS_TYPE_A) /* check if its for one of the service instances */ for (i=0;i<*numServers;i++) if(cm_stricmp_utf16(pDnsIter->pName, cellHostNames[i]) == 0) cellHostAddrs[i] = pDnsIter->Data.A.IpAddress; } for (i=0;i<*numServers;i++) { /* if we don't have an IP yet, then we should try resolving the service hostname in a separate query. */ if (!cellHostAddrs[i]) { if (DnsQuery_W(cellHostNames[i], DNS_TYPE_A, DNS_QUERY_STANDARD, NULL, (PDNS_RECORD *) &pDnsVol, NULL) == ERROR_SUCCESS) { for (pDnsVolIter = pDnsVol; pDnsVolIter; pDnsVolIter=pDnsVolIter->pNext) { /* if we get an A record, keep it */ if (pDnsVolIter->wType == DNS_TYPE_A && cm_stricmp_utf16(cellHostNames[i], pDnsVolIter->pName)==0) { cellHostAddrs[i] = pDnsVolIter->Data.A.IpAddress; break; } /* if we get a CNAME, look for a corresponding A record */ if (pDnsVolIter->wType == DNS_TYPE_CNAME && cm_stricmp_utf16(cellHostNames[i], pDnsVolIter->pName)==0) { for (pDnsCIter=pDnsVolIter; pDnsCIter; pDnsCIter=pDnsCIter->pNext) { if (pDnsCIter->wType == DNS_TYPE_A && cm_stricmp_utf16(pDnsVolIter->Data.CNAME.pNameHost, pDnsCIter->pName)==0) { cellHostAddrs[i] = pDnsCIter->Data.A.IpAddress; break; } } if (cellHostAddrs[i]) break; /* TODO: if the additional section is missing, then do another lookup for the CNAME */ } } /* we are done with the service lookup */ DnsRecordListFree((PDNS_RECORD) pDnsVol, DnsFreeRecordListDeep); } } } DnsRecordListFree((PDNS_RECORD) pDnsCell, DnsFreeRecordListDeep); } else { /* query the AFSDB records of cell */ StringCbCopyW(query, sizeof(query), cellName); if (query[wcslen(query)-1] != L'.') { StringCbCatW(query, sizeof(query), L"."); } if (DnsQuery_W(query, DNS_TYPE_AFSDB, DNS_QUERY_STANDARD, NULL, (PDNS_RECORD *) &pDnsCell, NULL) == ERROR_SUCCESS) { /* go through the returned records */ for (pDnsIter = pDnsCell;pDnsIter; pDnsIter = pDnsIter->pNext) { /* if we find an AFSDB record with Preference set to 1, we found a service instance */ if (pDnsIter->wType == DNS_TYPE_AFSDB && pDnsIter->Data.Afsdb.wPreference == 1) { StringCbCopyW(cellHostNames[*numServers], sizeof(cellHostNames[*numServers]), pDnsIter->Data.Afsdb.pNameExchange); ipRanks[*numServers] = 0; ports[*numServers] = afsdbPort; (*numServers)++; if (!*ttl) *ttl = pDnsIter->dwTtl; if (*numServers == AFSMAXCELLHOSTS) break; } } for (i=0;i<*numServers;i++) cellHostAddrs[i] = 0; /* now check if there are any A records in the results */ for (pDnsIter = pDnsCell; pDnsIter; pDnsIter = pDnsIter->pNext) { if(pDnsIter->wType == DNS_TYPE_A) /* check if its for one of the service instances */ for (i=0;i<*numServers;i++) if(cm_stricmp_utf16(pDnsIter->pName, cellHostNames[i]) == 0) cellHostAddrs[i] = pDnsIter->Data.A.IpAddress; } for (i=0;i<*numServers;i++) { /* if we don't have an IP yet, then we should try resolving the service hostname in a separate query. */ if (!cellHostAddrs[i]) { if (DnsQuery_W(cellHostNames[i], DNS_TYPE_A, DNS_QUERY_STANDARD, NULL, (PDNS_RECORD *) &pDnsVol, NULL) == ERROR_SUCCESS) { for (pDnsVolIter = pDnsVol; pDnsVolIter; pDnsVolIter=pDnsVolIter->pNext) { /* if we get an A record, keep it */ if (pDnsVolIter->wType == DNS_TYPE_A && cm_stricmp_utf16(cellHostNames[i], pDnsVolIter->pName)==0) { cellHostAddrs[i] = pDnsVolIter->Data.A.IpAddress; break; } /* if we get a CNAME, look for a corresponding A record */ if (pDnsVolIter->wType == DNS_TYPE_CNAME && cm_stricmp_utf16(cellHostNames[i], pDnsVolIter->pName)==0) { for (pDnsCIter=pDnsVolIter; pDnsCIter; pDnsCIter=pDnsCIter->pNext) { if (pDnsCIter->wType == DNS_TYPE_A && cm_stricmp_utf16(pDnsVolIter->Data.CNAME.pNameHost, pDnsCIter->pName)==0) { cellHostAddrs[i] = pDnsCIter->Data.A.IpAddress; break; } } if (cellHostAddrs[i]) break; /* TODO: if the additional section is missing, then do another lookup for the CNAME */ } } /* we are done with the service lookup */ DnsRecordListFree((PDNS_RECORD) pDnsVol, DnsFreeRecordListDeep); } } } DnsRecordListFree((PDNS_RECORD) pDnsCell, DnsFreeRecordListDeep); } } if ( *numServers > 0 ) return 0; else #endif /* DNSAPI_ENV */ return -1; }
QT_BEGIN_NAMESPACE void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, QDnsLookupReply *reply) { // Perform DNS query. PDNS_RECORD dns_records = 0; const QString requestNameUtf16 = QString::fromUtf8(requestName.data(), requestName.size()); const DNS_STATUS status = DnsQuery_W(reinterpret_cast<const wchar_t*>(requestNameUtf16.utf16()), requestType, DNS_QUERY_STANDARD, NULL, &dns_records, NULL); switch (status) { case ERROR_SUCCESS: break; case DNS_ERROR_RCODE_FORMAT_ERROR: reply->error = QDnsLookup::InvalidRequestError; reply->errorString = tr("Server could not process query"); return; case DNS_ERROR_RCODE_SERVER_FAILURE: reply->error = QDnsLookup::ServerFailureError; reply->errorString = tr("Server failure"); return; case DNS_ERROR_RCODE_NAME_ERROR: reply->error = QDnsLookup::NotFoundError; reply->errorString = tr("Non existent domain"); return; case DNS_ERROR_RCODE_REFUSED: reply->error = QDnsLookup::ServerRefusedError; reply->errorString = tr("Server refused to answer"); return; default: reply->error = QDnsLookup::InvalidReplyError; reply->errorString = QSystemError(status, QSystemError::NativeError).toString(); return; } // Extract results. for (PDNS_RECORD ptr = dns_records; ptr != NULL; ptr = ptr->pNext) { const QString name = QUrl::fromAce( QString::fromWCharArray( ptr->pName ).toLatin1() ); if (ptr->wType == QDnsLookup::A) { QDnsHostAddressRecord record; record.d->name = name; record.d->timeToLive = ptr->dwTtl; record.d->value = QHostAddress(ntohl(ptr->Data.A.IpAddress)); reply->hostAddressRecords.append(record); } else if (ptr->wType == QDnsLookup::AAAA) { Q_IPV6ADDR addr; memcpy(&addr, &ptr->Data.AAAA.Ip6Address, sizeof(Q_IPV6ADDR)); QDnsHostAddressRecord record; record.d->name = name; record.d->timeToLive = ptr->dwTtl; record.d->value = QHostAddress(addr); reply->hostAddressRecords.append(record); } else if (ptr->wType == QDnsLookup::CNAME) { QDnsDomainNameRecord record; record.d->name = name; record.d->timeToLive = ptr->dwTtl; record.d->value = QUrl::fromAce(QString::fromWCharArray(ptr->Data.Cname.pNameHost).toLatin1()); reply->canonicalNameRecords.append(record); } else if (ptr->wType == QDnsLookup::MX) { QDnsMailExchangeRecord record; record.d->name = name; record.d->exchange = QUrl::fromAce(QString::fromWCharArray(ptr->Data.Mx.pNameExchange).toLatin1()); record.d->preference = ptr->Data.Mx.wPreference; record.d->timeToLive = ptr->dwTtl; reply->mailExchangeRecords.append(record); } else if (ptr->wType == QDnsLookup::NS) { QDnsDomainNameRecord record; record.d->name = name; record.d->timeToLive = ptr->dwTtl; record.d->value = QUrl::fromAce(QString::fromWCharArray(ptr->Data.Ns.pNameHost).toLatin1()); reply->nameServerRecords.append(record); } else if (ptr->wType == QDnsLookup::PTR) { QDnsDomainNameRecord record; record.d->name = name; record.d->timeToLive = ptr->dwTtl; record.d->value = QUrl::fromAce(QString::fromWCharArray(ptr->Data.Ptr.pNameHost).toLatin1()); reply->pointerRecords.append(record); } else if (ptr->wType == QDnsLookup::SRV) { QDnsServiceRecord record; record.d->name = name; record.d->target = QUrl::fromAce(QString::fromWCharArray(ptr->Data.Srv.pNameTarget).toLatin1()); record.d->port = ptr->Data.Srv.wPort; record.d->priority = ptr->Data.Srv.wPriority; record.d->timeToLive = ptr->dwTtl; record.d->weight = ptr->Data.Srv.wWeight; reply->serviceRecords.append(record); } else if (ptr->wType == QDnsLookup::TXT) { QDnsTextRecord record; record.d->name = name; record.d->timeToLive = ptr->dwTtl; for (unsigned int i = 0; i < ptr->Data.Txt.dwStringCount; ++i) { record.d->values << QString::fromWCharArray((ptr->Data.Txt.pStringArray[i])).toLatin1();; } reply->textRecords.append(record); } } DnsRecordListFree(dns_records, DnsFreeRecordList); }
int getAFSServerW(cm_unichar_t *cellName, int *cellHostAddrs, cm_unichar_t cellHostNames[][MAXHOSTCHARS], int *numServers, int *ttl) { #ifdef DNSAPI_ENV PDNS_RECORDW pDnsCell, pDnsIter, pDnsVol,pDnsVolIter, pDnsCIter; int i; struct sockaddr_in vlSockAddr; cm_unichar_t query[1024]; #ifdef AFS_FREELANCE_CLIENT if ( cm_stricmp_utf16(cellName, L"Freelance.Local.Root") == 0 ) return -1; #endif /* AFS_FREELANCE_CLIENT */ *numServers = 0; *ttl = 0; /* query the AFSDB records of cell */ StringCbCopyW(query, sizeof(query), cellName); if (query[wcslen(query)-1] != L'.') { StringCbCatW(query, sizeof(query), L"."); } if (DnsQuery_W(query, DNS_TYPE_AFSDB, DNS_QUERY_STANDARD, NULL, (PDNS_RECORD *) &pDnsCell, NULL) == ERROR_SUCCESS) { memset((void*) &vlSockAddr, 0, sizeof(vlSockAddr)); /* go through the returned records */ for (pDnsIter = pDnsCell;pDnsIter; pDnsIter = pDnsIter->pNext) { /* if we find an AFSDB record with Preference set to 1, we found a volserver */ if (pDnsIter->wType == DNS_TYPE_AFSDB && pDnsIter->Data.Afsdb.wPreference == 1) { StringCbCopyW(cellHostNames[*numServers], sizeof(cellHostNames[*numServers]), pDnsIter->Data.Afsdb.pNameExchange); (*numServers)++; if (!*ttl) *ttl = pDnsIter->dwTtl; if (*numServers == AFSMAXCELLHOSTS) break; } } for (i=0;i<*numServers;i++) cellHostAddrs[i] = 0; /* now check if there are any A records in the results */ for (pDnsIter = pDnsCell; pDnsIter; pDnsIter = pDnsIter->pNext) { if(pDnsIter->wType == DNS_TYPE_A) /* check if its for one of the volservers */ for (i=0;i<*numServers;i++) if(cm_stricmp_utf16(pDnsIter->pName, cellHostNames[i]) == 0) cellHostAddrs[i] = pDnsIter->Data.A.IpAddress; } for (i=0;i<*numServers;i++) { /* if we don't have an IP yet, then we should try resolving the volserver hostname in a separate query. */ if (!cellHostAddrs[i]) { if (DnsQuery_W(cellHostNames[i], DNS_TYPE_A, DNS_QUERY_STANDARD, NULL, (PDNS_RECORD *) &pDnsVol, NULL) == ERROR_SUCCESS) { for (pDnsVolIter = pDnsVol; pDnsVolIter; pDnsVolIter=pDnsVolIter->pNext) { /* if we get an A record, keep it */ if (pDnsVolIter->wType == DNS_TYPE_A && cm_stricmp_utf16(cellHostNames[i], pDnsVolIter->pName)==0) { cellHostAddrs[i] = pDnsVolIter->Data.A.IpAddress; break; } /* if we get a CNAME, look for a corresponding A record */ if (pDnsVolIter->wType == DNS_TYPE_CNAME && cm_stricmp_utf16(cellHostNames[i], pDnsVolIter->pName)==0) { for (pDnsCIter=pDnsVolIter; pDnsCIter; pDnsCIter=pDnsCIter->pNext) { if (pDnsCIter->wType == DNS_TYPE_A && cm_stricmp_utf16(pDnsVolIter->Data.CNAME.pNameHost, pDnsCIter->pName)==0) { cellHostAddrs[i] = pDnsCIter->Data.A.IpAddress; break; } } if (cellHostAddrs[i]) break; /* TODO: if the additional section is missing, then do another lookup for the CNAME */ } } /* we are done with the volserver lookup */ DnsRecordListFree((PDNS_RECORD) pDnsVol, DnsFreeRecordListDeep); } } } DnsRecordListFree((PDNS_RECORD) pDnsCell, DnsFreeRecordListDeep); } if ( *numServers > 0 ) return 0; else #endif /* DNSAPI_ENV */ return -1; }