#include <afs/param.h>
#include <afs/stds.h>
+#include <afs/cellconfig.h>
#ifndef DJGPP
#include <windows.h>
#include <winsock2.h>
#include "cm_dns.h"
#include <lwp.h>
#include <afs/afsint.h>
+#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0500)
+#include <windns.h>
+#define DNSAPI_ENV
+#endif
/*extern void afsi_log(char *pattern, ...);*/
int cm_InitDNS(int enabled)
{
+#ifndef DNSAPI_ENV
char configpath[100];
int len;
int code;
}
else fprintf(stderr, "Found DNS server %s\n", dns_addr);
}
-
+#endif /* DNSAPI_ENV */
cm_dnsEnabled = 1;
return 0;
}
+#ifndef DNSAPI_ENV
SOCKADDR_IN setSockAddr(char *server, int port)
{
SOCKADDR_IN sockAddr;
};
-void processReplyBuffer_AFSDB(SOCKET commSock, PDNS_HDR replyBuff, int *cellHosts, int *numServers, int *ttl)
+void processReplyBuffer_AFSDB(SOCKET commSock, PDNS_HDR replyBuff, int *cellHostAddrs, char cellHostNames[][MAXHOSTCHARS], int *numServers, int *ttl)
/*PAFS_SRV_LIST (srvList)*/
{
u_char *ptr = (u_char *) replyBuff;
#ifdef DEBUG
fprintf(stderr, "processRep_AFSDB: resolved name %s to addr %x\n", hostName, addr);
#endif /* DEBUG */
- memcpy(&cellHosts[srvCount], &addr.s_addr, sizeof(addr.s_addr));
+ memcpy(&cellHostAddrs[srvCount], &addr.s_addr, sizeof(addr.s_addr));
+ strncpy(cellHostNames[srvCount], hostName, MAXCELLCHARS);
+ cellHostNames[srvCount][MAXCELLCHARS-1] = '\0';
srvCount++;
}
else {
};
-int getAFSServer(char *cellName, int *cellHosts, int *numServers, int *ttl)
+int DNSgetAddr(SOCKET commSock, char *hostName, struct in_addr *iNet)
+{
+ /* Variables for DNS message parsing and creation */
+ PDNS_HDR pDNShdr;
+
+ SOCKADDR_IN sockAddr;
+ char buffer[BUFSIZE];
+ u_char *addr;
+ u_long *aPtr;
+ int rc;
+
+ /**********************
+ * Get a DGRAM socket *
+ **********************/
+
+ sockAddr = setSockAddr(dns_addr, DNS_PORT);
+
+ rc = send_DNS_Addr_Query(hostName,commSock,sockAddr, buffer);
+ if (rc < 0) return rc;
+ pDNShdr = get_DNS_Response(commSock,sockAddr, buffer);
+ if (pDNShdr == NULL)
+ return -1;
+
+ addr = processReplyBuffer_Addr(pDNShdr);
+ if (addr == 0)
+ return -1;
+
+ aPtr = (u_long *) addr;
+
+ iNet->s_addr = *aPtr;
+
+ return(0);
+}
+#endif /* DNSAPI_ENV */
+
+int getAFSServer(char *cellName, int *cellHostAddrs, char cellHostNames[][MAXHOSTCHARS],
+ int *numServers, int *ttl)
{
- /*static AFS_SRV_LIST srvList;
+#ifndef DNSAPI_ENV
+ /*static AFS_SRV_LIST srvList;
static int ans = 0;*/
SOCKET commSock;
SOCKADDR_IN sockAddr;
fprintf(stderr, "getAFSServer: cell %s, cm_dnsEnabled=%d\n", cellName, cm_dnsEnabled);
#endif
-#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x500
+#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500)
if (cm_dnsEnabled == -1) { /* not yet initialized, eg when called by klog */
cm_InitDNS(1); /* assume enabled */
}
/*printReplyBuffer_AFSDB(pDNShdr);*/
if (pDNShdr)
- processReplyBuffer_AFSDB(commSock, pDNShdr, cellHosts, numServers, ttl);
+ processReplyBuffer_AFSDB(commSock, pDNShdr, cellHostAddrs, cellHostNames, numServers, ttl);
else
*numServers = 0;
else
return 0;
-}
-
-int DNSgetAddr(SOCKET commSock, char *hostName, struct in_addr *iNet)
-{
- /* Variables for DNS message parsing and creation */
- PDNS_HDR pDNShdr;
-
- SOCKADDR_IN sockAddr;
- char buffer[BUFSIZE];
- u_char *addr;
- u_long *aPtr;
- int rc;
-
- /**********************
- * Get a DGRAM socket *
- **********************/
-
- sockAddr = setSockAddr(dns_addr, DNS_PORT);
-
- rc = send_DNS_Addr_Query(hostName,commSock,sockAddr, buffer);
- if (rc < 0) return rc;
- pDNShdr = get_DNS_Response(commSock,sockAddr, buffer);
- if (pDNShdr == NULL)
- return -1;
-
- addr = processReplyBuffer_Addr(pDNShdr);
- if (addr == 0)
- return -1;
-
- aPtr = (u_long *) addr;
-
- iNet->s_addr = *aPtr;
+#else /* DNSAPI_ENV */
+ PDNS_RECORD pDnsCell, pDnsIter, pDnsVol,pDnsVolIter, pDnsCIter;
+ DWORD i;
+ struct sockaddr_in vlSockAddr;
+
+ /* 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)++;
+
+ 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(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])
+ 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);
+ }
- return(0);
+ if ( *numServers > 0 )
+ return 0;
+ else
+ return -1;
+#endif /* DNSAPI_ENV */
}
#endif /* AFS_AFSDB_ENV */