#include <afs/param.h>
#include <afs/stds.h>
#include <afs/cellconfig.h>
-#ifndef DJGPP
#include <windows.h>
#include <winsock2.h>
-#endif
#include "cm_dns_private.h"
+#include "cm_nls.h"
#include "cm_dns.h"
#include <lwp.h>
#include <afs/afsint.h>
#include <windns.h>
#define DNSAPI_ENV
#endif
+#include <errno.h>
+#include <strsafe.h>
/*extern void afsi_log(char *pattern, ...);*/
-extern int errno;
static char dns_addr[30];
-#ifdef DJGPP
-extern char cm_confDir[];
-#endif
static int cm_dnsEnabled = -1;
void DNSlowerCase(char *str)
{
- int i;
+ unsigned int i;
- for (i=0; i<strlen(str); i++)
- /*str[i] = tolower(str[i]);*/
- if (str[i] >= 'A' && str[i] <= 'Z')
- str[i] += 'a' - 'A';
+ for (i=0; i<strlen(str); i++)
+ /*str[i] = tolower(str[i]);*/
+ if (str[i] >= 'A' && str[i] <= 'Z')
+ str[i] += 'a' - 'A';
}
int cm_InitDNS(int enabled)
{
#ifndef DNSAPI_ENV
- char configpath[100];
- int len;
- int code;
- char *addr;
-
- if (!enabled) { fprintf(stderr, "DNS support disabled\n"); cm_dnsEnabled = 0; return 0; }
-
- /* First try AFS_NS environment var. */
- addr = getenv("AFS_NS");
- if (addr && inet_addr(addr) != -1) {
- strcpy(dns_addr, addr);
- } else {
- /* Now check for the AFSDNS.INI file */
-#ifdef DJGPP
- strcpy(configpath, cm_confDir);
-#elif defined(AFS_WIN95_ENV)
- char *path = getenv("AFSCONF");
- if (path) strcpy(configpath, path);
- else strcpy(configpath, "c:\\afscli");
-#else /* nt */
- code = GetWindowsDirectory(configpath, sizeof(configpath));
- if (code == 0 || code > sizeof(configpath)) return -1;
-#endif
- strcat(configpath, "\\afsdns.ini");
-
- /* Currently we only get (and query) the first nameserver. Getting
- list of mult. nameservers should be easy to do. */
- len = GetPrivateProfileString("AFS Domain Name Servers", "ns1", NULL,
- dns_addr, sizeof(dns_addr),
- configpath);
-
- if (len == 0 || inet_addr(dns_addr) == -1) {
- fprintf(stderr, "No valid name server addresses found, DNS lookup is "
- "disabled\n");
- cm_dnsEnabled = 0; /* failed */
- return -1; /* No name servers defined */
+ char configpath[100];
+ int len;
+ int code;
+ char *addr;
+
+ if (!enabled) {
+ fprintf(stderr, "DNS support disabled\n");
+ cm_dnsEnabled = 0;
+ return 0;
+ }
+
+ /* First try AFS_NS environment var. */
+ addr = getenv("AFS_NS");
+ if (addr && inet_addr(addr) != -1) {
+ strcpy(dns_addr, addr);
+ } else {
+ /* Now check for the AFSDNS.INI file */
+ code = GetWindowsDirectory(configpath, sizeof(configpath));
+ if (code == 0 || code > sizeof(configpath)) return -1;
+ strcat(configpath, "\\afsdns.ini");
+
+ /* Currently we only get (and query) the first nameserver. Getting
+ list of mult. nameservers should be easy to do. */
+ len = GetPrivateProfileString("AFS Domain Name Servers", "ns1", NULL,
+ dns_addr, sizeof(dns_addr),
+ configpath);
+
+ if (len == 0 || inet_addr(dns_addr) == -1) {
+ fprintf(stderr, "No valid name server addresses found, DNS lookup is "
+ "disabled\n");
+ cm_dnsEnabled = 0; /* failed */
+ return -1; /* No name servers defined */
+ }
+ else
+ fprintf(stderr, "Found DNS server %s\n", dns_addr);
}
- else fprintf(stderr, "Found DNS server %s\n", dns_addr);
- }
#endif /* DNSAPI_ENV */
- cm_dnsEnabled = 1;
- return 0;
+ cm_dnsEnabled = 1;
+ return 0;
}
#ifndef DNSAPI_ENV
};
-void processReplyBuffer_AFSDB(SOCKET commSock, PDNS_HDR replyBuff, int *cellHostAddrs, char cellHostNames[][MAXHOSTCHARS], int *numServers, int *ttl)
+void processReplyBuffer_AFSDB(SOCKET commSock, PDNS_HDR replyBuff, int *cellHostAddrs, char cellHostNames[][MAXHOSTCHARS],
+ unsigned short ipRanks[], int *numServers, int *ttl)
/*PAFS_SRV_LIST (srvList)*/
{
u_char *ptr = (u_char *) replyBuff;
fprintf(stderr, "processRep_AFSDB: resolved name %s to addr %x\n", hostName, addr);
#endif /* DEBUG */
memcpy(&cellHostAddrs[srvCount], &addr.s_addr, sizeof(addr.s_addr));
- strncpy(cellHostNames[srvCount], hostName, MAXCELLCHARS);
- cellHostNames[srvCount][MAXCELLCHARS-1] = '\0';
+ strncpy(cellHostNames[srvCount], hostName, CELL_MAXNAMELEN);
+ cellHostNames[srvCount][CELL_MAXNAMELEN-1] = '\0';
+ ipRanks[srvCount] = 0;
srvCount++;
}
else {
#endif /* DNSAPI_ENV */
int getAFSServer(char *cellName, int *cellHostAddrs, char cellHostNames[][MAXHOSTCHARS],
- int *numServers, int *ttl)
+ unsigned short ipRanks[], int *numServers, int *ttl)
{
#ifndef DNSAPI_ENV
- /*static AFS_SRV_LIST srvList;
- static int ans = 0;*/
- SOCKET commSock;
- SOCKADDR_IN sockAddr;
- PDNS_HDR pDNShdr;
- char buffer[BUFSIZE];
- int rc;
+ SOCKET commSock;
+ SOCKADDR_IN sockAddr;
+ PDNS_HDR pDNShdr;
+ char buffer[BUFSIZE];
+ char query[1024];
+ int rc;
#ifdef DEBUG
- fprintf(stderr, "getAFSServer: cell %s, cm_dnsEnabled=%d\n", cellName, cm_dnsEnabled);
+ fprintf(stderr, "getAFSServer: cell %s, cm_dnsEnabled=%d\n", cellName, cm_dnsEnabled);
#endif
#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500)
- if (cm_dnsEnabled == -1) { /* not yet initialized, eg when called by klog */
- cm_InitDNS(1); /* assume enabled */
- }
+ if (cm_dnsEnabled == -1) { /* not yet initialized, eg when called by klog */
+ cm_InitDNS(1); /* assume enabled */
+ }
#endif
- if (cm_dnsEnabled == 0) { /* possibly we failed in cm_InitDNS above */
- fprintf(stderr, "DNS initialization failed, disabled\n");
- *numServers = 0;
- return -1;
- }
+ if (cm_dnsEnabled == 0) { /* possibly we failed in cm_InitDNS above */
+ fprintf(stderr, "DNS initialization failed, disabled\n");
+ *numServers = 0;
+ return -1;
+ }
- sockAddr = setSockAddr(dns_addr, DNS_PORT);
+ sockAddr = setSockAddr(dns_addr, DNS_PORT);
- commSock = socket( AF_INET, SOCK_DGRAM, 0 );
- if ( commSock < 0 )
+ commSock = socket( AF_INET, SOCK_DGRAM, 0 );
+ if ( commSock < 0 )
{
- /*afsi_log("socket() failed\n");*/
- fprintf(stderr, "getAFSServer: socket() failed, errno=%d\n", errno);
- *numServers = 0;
- return (-1);
+ /*afsi_log("socket() failed\n");*/
+ fprintf(stderr, "getAFSServer: socket() failed, errno=%d\n", errno);
+ *numServers = 0;
+ return (-1);
}
-
-#ifdef DJGPP
- /* the win95 sock.vxd will not allow sendto for unbound sockets,
- * so just bind to nothing and it works */
-
- __djgpp_set_socket_blocking_mode(commSock, 0);
- bind(commSock,0,sizeof( SOCKADDR_IN ) );
-#endif /* DJGPP */
- rc = send_DNS_AFSDB_Query(cellName,commSock,sockAddr, buffer);
- if (rc < 0) {
- fprintf(stderr,"getAFSServer: send_DNS_AFSDB_Query failed\n");
- *numServers = 0;
- return -1;
- }
+ StringCbCopyA(query, sizeof(query), cellName);
+ if (query[strlen(query)-1] != '.') {
+ StringCbCatA(query, sizeof(query), ".");
+ }
+
+ rc = send_DNS_AFSDB_Query(cellName,commSock,sockAddr, buffer);
+ if (rc < 0) {
+ closesocket(commSock);
+ fprintf(stderr,"getAFSServer: send_DNS_AFSDB_Query failed\n");
+ *numServers = 0;
+ return -1;
+ }
- pDNShdr = get_DNS_Response(commSock,sockAddr, buffer);
+ pDNShdr = get_DNS_Response(commSock,sockAddr, buffer);
- /*printReplyBuffer_AFSDB(pDNShdr);*/
- if (pDNShdr)
- processReplyBuffer_AFSDB(commSock, pDNShdr, cellHostAddrs, cellHostNames, numServers, ttl);
- else
- *numServers = 0;
-
- closesocket(commSock);
- if (*numServers == 0)
- return(-1);
+ /*printReplyBuffer_AFSDB(pDNShdr);*/
+ if (pDNShdr)
+ processReplyBuffer_AFSDB(commSock, pDNShdr, cellHostAddrs, cellHostNames, ipRanks, numServers, ttl);
+ else
+ *numServers = 0;
- else
- return 0;
+ closesocket(commSock);
+ if (*numServers == 0)
+ return(-1);
+ else
+ return 0;
#else /* DNSAPI_ENV */
- PDNS_RECORD pDnsCell, pDnsIter, pDnsVol,pDnsVolIter, pDnsCIter;
- DWORD i;
+ PDNS_RECORD pDnsCell, pDnsIter, pDnsVol, pDnsVolIter, pDnsCIter;
+ int i;
struct sockaddr_in vlSockAddr;
+ char query[1024];
+
+#ifdef AFS_FREELANCE_CLIENT
+ if ( cm_stricmp_utf8N(cellName, "Freelance.Local.Root") == 0 )
+ return -1;
+#endif /* AFS_FREELANCE_CLIENT */
+
+ *numServers = 0;
+ *ttl = 0;
/* query the AFSDB records of cell */
- if (DnsQuery_A(cellName, DNS_TYPE_AFSDB, DNS_QUERY_STANDARD, NULL, &pDnsCell, NULL) == ERROR_SUCCESS) {
-
- memset((void*) &vlSockAddr, 0, sizeof(vlSockAddr));
-
- *numServers = 0;
- *ttl = 0;
-
- /* 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) {
- strncpy(cellHostNames[*numServers], pDnsIter->Data.Afsdb.pNameExchange, MAXHOSTCHARS);
- cellHostNames[*numServers][MAXHOSTCHARS-1]='\0';
- (*numServers)++;
+ StringCbCopyA(query, sizeof(query), cellName);
+ if (query[strlen(query)-1] != '.') {
+ StringCbCatA(query, sizeof(query), ".");
+ }
+
+ if (DnsQuery_A(query, DNS_TYPE_AFSDB, DNS_QUERY_STANDARD, NULL, &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 afs3-vlserver */
+ if (pDnsIter->wType == DNS_TYPE_AFSDB && pDnsIter->Data.Afsdb.wPreference == 1) {
+ StringCbCopyA(cellHostNames[*numServers], sizeof(cellHostNames[*numServers]),
+ pDnsIter->Data.Afsdb.pNameExchange);
+ ipRanks[*numServers] = 0;
+ (*numServers)++;
- if (!*ttl)
+ if (!*ttl)
*ttl = pDnsIter->dwTtl;
- if (*numServers == AFSMAXCELLHOSTS)
+ if (*numServers == AFSMAXCELLHOSTS)
break;
- }
- }
+ }
+ }
- for (i=0;i<*numServers;i++)
+ 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(stricmp(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_A(cellHostNames[i], DNS_TYPE_A, DNS_QUERY_STANDARD, NULL, &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 && stricmp(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 && stricmp(cellHostNames[i], pDnsVolIter->pName)==0) {
- for (pDnsCIter=pDnsVolIter; pDnsCIter; pDnsCIter=pDnsCIter->pNext) {
- if (pDnsCIter->wType == DNS_TYPE_A && stricmp(pDnsVolIter->Data.CNAME.pNameHost, pDnsCIter->pName)==0) {
- cellHostAddrs[i] = pDnsCIter->Data.A.IpAddress;
- break;
- }
- }
- if (cellHostAddrs[i])
+ /* 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 afs3-vlservers */
+ for (i=0;i<*numServers;i++)
+ if(cm_stricmp_utf8(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 afs3-vlserver hostname
+ in a separate query. */
+ if (!cellHostAddrs[i]) {
+ if (DnsQuery_A(cellHostNames[i], DNS_TYPE_A, DNS_QUERY_STANDARD, NULL, &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_utf8(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_utf8(cellHostNames[i], pDnsVolIter->pName)==0) {
+ for (pDnsCIter=pDnsVolIter; pDnsCIter; pDnsCIter=pDnsCIter->pNext) {
+ if (pDnsCIter->wType == DNS_TYPE_A && cm_stricmp_utf8(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(pDnsVol, DnsFreeRecordListDeep);
- }
- }
- }
- DnsRecordListFree(pDnsCell, DnsFreeRecordListDeep);
- }
+ /* TODO: if the additional section is missing, then do another lookup for the CNAME */
+ }
+ }
+ /* we are done with the afs3-vlserver lookup */
+ DnsRecordListFree(pDnsVol, DnsFreeRecordListDeep);
+ }
+ }
+ }
+ DnsRecordListFree(pDnsCell, DnsFreeRecordListDeep);
+ }
+ else {
+ /* query the SRV _afs3-vlserver._udp records of cell */
+ StringCbPrintf(query, sizeof(query), "_afs3-vlserver._udp.%s", cellName);
+ if (query[strlen(query)-1] != '.') {
+ StringCbCatA(query, sizeof(query), ".");
+ }
+
+ if (DnsQuery_A(query, DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, &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 SRV record, we found a afs3-vlserver */
+ if (pDnsIter->wType == DNS_TYPE_SRV) {
+ StringCbCopyA(cellHostNames[*numServers], sizeof(cellHostNames[*numServers]),
+ pDnsIter->Data.SRV.pNameTarget);
+ ipRanks[*numServers] = pDnsIter->Data.SRV.wPriority;
+ (*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 afs3-vlservers */
+ for (i=0;i<*numServers;i++)
+ if(cm_stricmp_utf8(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 afs3-vlserver hostname
+ in a separate query. */
+ if (!cellHostAddrs[i]) {
+ if (DnsQuery_A(cellHostNames[i], DNS_TYPE_A, DNS_QUERY_STANDARD, NULL, &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_utf8(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_utf8(cellHostNames[i], pDnsVolIter->pName)==0) {
+ for (pDnsCIter=pDnsVolIter; pDnsCIter; pDnsCIter=pDnsCIter->pNext) {
+ if (pDnsCIter->wType == DNS_TYPE_A && cm_stricmp_utf8(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 afs3-vlserver lookup */
+ DnsRecordListFree(pDnsVol, DnsFreeRecordListDeep);
+ }
+ }
+ }
+ DnsRecordListFree(pDnsCell, DnsFreeRecordListDeep);
+ }
+ }
if ( *numServers > 0 )
return 0;
- else
+ else
return -1;
#endif /* DNSAPI_ENV */
}
+int getAFSServerW(cm_unichar_t *cellName, int *cellHostAddrs,
+ cm_unichar_t cellHostNames[][MAXHOSTCHARS],
+ unsigned short ipRanks[],
+ 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 afs3-vlserver */
+ if (pDnsIter->wType == DNS_TYPE_AFSDB && pDnsIter->Data.Afsdb.wPreference == 1) {
+ StringCbCopyW(cellHostNames[*numServers], sizeof(cellHostNames[*numServers]),
+ pDnsIter->Data.Afsdb.pNameExchange);
+ ipRanks[*numServers] = 0;
+ (*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 afs3-vlservers */
+ 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 afs3-vlserver 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 afs3-vlserver lookup */
+ DnsRecordListFree((PDNS_RECORD) pDnsVol, DnsFreeRecordListDeep);
+ }
+ }
+ }
+ DnsRecordListFree((PDNS_RECORD) pDnsCell, DnsFreeRecordListDeep);
+ }
+ else {
+ /* query the SRV _afs3-vlserver._udp records of cell */
+ StringCbPrintfW(query, sizeof(query), L"_afs3-vlserver._udp.%S", 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) {
+ memset((void*) &vlSockAddr, 0, sizeof(vlSockAddr));
+
+ /* go through the returned records */
+ for (pDnsIter = pDnsCell; pDnsIter; pDnsIter = pDnsIter->pNext) {
+ /* if we find an SRV record, we found a afs3-vlserver */
+ if (pDnsIter->wType == DNS_TYPE_SRV) {
+ StringCbCopyW(cellHostNames[*numServers], sizeof(cellHostNames[*numServers]),
+ pDnsIter->Data.SRV.pNameTarget);
+ ipRanks[*numServers] = pDnsIter->Data.SRV.wPriority;
+ (*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 afs3-vlservers */
+ 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 afs3-vlserver 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 afs3-vlserver lookup */
+ DnsRecordListFree((PDNS_RECORD) pDnsVol, DnsFreeRecordListDeep);
+ }
+ }
+ }
+ DnsRecordListFree((PDNS_RECORD) pDnsCell, DnsFreeRecordListDeep);
+ }
+ }
+
+ if ( *numServers > 0 )
+ return 0;
+ else
+#endif /* DNSAPI_ENV */
+ return -1;
+}
#endif /* AFS_AFSDB_ENV */
+