]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
Permit DNS SRV record lookups to be used by the Windows afsconf_GetAfsdbInfo
authorJeffrey Altman <jaltman@your-file-system.com>
Tue, 6 Oct 2009 18:46:09 +0000 (14:46 -0400)
committerJeffrey Altman <jaltman|account-1000011@unknown>
Thu, 8 Oct 2009 11:07:08 +0000 (04:07 -0700)
Permit DNS SRV record lookups to be used by the Windows afsconf_GetAfsdbInfo

As per the published DNS SRV internet draft for the AFS3 protocol,
DNS SRV records are to replace AFSDB records as the primary method
of looking up AFS3 service location information.

In order to make that happen for Windows:

1. afsconf_GetAfsdbInfo must be able to translate from internal service
names to IANA assigned service names.

2. The Windows getAFSServer() API must accept IANA service and protocol
parameters as well as the port number to use if AFSDB record fallback is
required.

3. The Windows cache manager must pay attention to the port number
stored within the sockaddr_in structure instead of using hard coded
values based upon the server type.
For afsconf_GetAfsdbInfo, in addition to searching for the requested
IANA service, if that service is prserver or kaserver fallback to
the vlserver record (if any).

LICENSE MIT

Reviewed-on: http://gerrit.openafs.org/593
Reviewed-by: Jeffrey Altman <jaltman@openafs.org>
Tested-by: Jeffrey Altman <jaltman@openafs.org>
src/WINNT/afsd/afsd_init.c
src/WINNT/afsd/cm_callback.c
src/WINNT/afsd/cm_config.c
src/WINNT/afsd/cm_conn.c
src/WINNT/afsd/cm_dns.c
src/WINNT/afsd/cm_dns.h
src/WINNT/afsd/cm_ioctl.c
src/WINNT/afsd/cm_server.c
src/WINNT/afsd/cm_volume.c
src/auth/cellconfig.c

index ab38b55232507bde37413364df5dd1955cdf059b..d9f85f348f3d5b180a774afda614e4e91703e86f 100644 (file)
@@ -297,6 +297,7 @@ static void afsd_InitServerPreferences(void)
 
                 saddr.sin_addr.S_un.S_addr = *(unsigned long *)pEntry->h_addr;
             }
+            saddr.sin_port = htons(7003);
             saddr.sin_family = AF_INET;
             dwRank += (rand() & 0x000f);
 
@@ -370,6 +371,7 @@ static void afsd_InitServerPreferences(void)
 
                 saddr.sin_addr.S_un.S_addr = *(unsigned long *)pEntry->h_addr;
             }
+            saddr.sin_port = htons(7000);
             saddr.sin_family = AF_INET;
             dwRank += (rand() & 0x000f);
 
index 006cedb48ce3ac241e386621656210d6425a4b81..d5e36da483baa06734bbdc4b030c953ab0033204 100644 (file)
@@ -1002,6 +1002,7 @@ SRXAFSCB_InitCallBackState3(struct rx_call *callp, afsUUID* serverUuid)
     if (connp && peerp) {
        taddr.sin_family = AF_INET;
        taddr.sin_addr.s_addr = rx_HostOf(rx_PeerOf(rx_ConnectionOf(callp)));
+       taddr.sin_port = rx_PortOf(rx_PeerOf(rx_ConnectionOf(callp)));
 
        tsp = cm_FindServer(&taddr, CM_SERVER_FILE);
 
index b54216c75b114d188c76208ec37346e217e12a06..534bbdef87f8f0c4563cc273d7ee16420aa6d7a1 100644 (file)
@@ -306,6 +306,7 @@ long cm_SearchCellFileEx(char *cellNamep, char *newCellNamep,
                             continue;
                         memcpy(&vlSockAddr.sin_addr.s_addr, thp->h_addr_list[i],
                                sizeof(long));
+                        vlSockAddr.sin_port = htons(7003);
                         vlSockAddr.sin_family = AF_INET;
                         /* sin_port supplied by connection code */
                         if (procp)
@@ -338,6 +339,7 @@ long cm_SearchCellFileEx(char *cellNamep, char *newCellNamep,
                         *tp++ = c4;
                         memcpy(&vlSockAddr.sin_addr.s_addr, &ip_addr,
                                 sizeof(long));
+                        vlSockAddr.sin_port = htons(7003);
                         vlSockAddr.sin_family = AF_INET;
                         /* sin_port supplied by connection code */
                         if (procp)
@@ -369,7 +371,7 @@ long cm_SearchCellFileEx(char *cellNamep, char *newCellNamep,
  *   "Rank"          DWORD  "0..65535"
  *   "Clone"         DWORD  "{0,1}"
  *   "vlserver"      DWORD  "7003"        <future>
- *   "ptserver"      DWORD  ...           <future>
+ *   "ptserver"      DWORD  "7002"        <future>
  *
  * ForceDNS is implied non-zero if there are no [servername]
  * keys under the [cellname] key.  Otherwise, ForceDNS is zero.
@@ -385,8 +387,9 @@ long cm_SearchCellRegistry(afs_uint32 client,
     HKEY hkCellServDB = 0, hkCellName = 0, hkServerName = 0;
     DWORD dwType, dwSize;
     DWORD dwCells, dwServers, dwForceDNS;
-    DWORD dwIndex, dwRank;
+    DWORD dwIndex, dwRank, dwPort;
     unsigned short ipRank;
+    unsigned short vlPort;
     LONG code;
     FILETIME ftLastWriteTime;
     char szCellName[CELL_MAXNAMELEN];
@@ -576,10 +579,20 @@ long cm_SearchCellRegistry(afs_uint32 client,
             szAddr[0] = '\0';
         }
 
+        dwSize = sizeof(DWORD);
+        code = RegQueryValueEx(hkServerName, "vlserver", NULL, &dwType,
+                                (BYTE *) &dwPort, &dwSize);
+        if (code == ERROR_SUCCESS && dwType == REG_DWORD) {
+            vlPort = htons((unsigned short)dwPort);
+        } else {
+            vlPort = htons(7003);
+        }
+
         WSASetLastError(0);
         thp = gethostbyname(s);
         if (thp) {
             memcpy(&vlSockAddr.sin_addr.s_addr, thp->h_addr, sizeof(long));
+            vlSockAddr.sin_port = htons(7003);
             vlSockAddr.sin_family = AF_INET;
             /* sin_port supplied by connection code */
             if (procp)
@@ -602,6 +615,7 @@ long cm_SearchCellRegistry(afs_uint32 client,
                 *tp++ = c4;
                 memcpy(&vlSockAddr.sin_addr.s_addr, &ip_addr,
                         sizeof(long));
+                vlSockAddr.sin_port = vlPort;
                 vlSockAddr.sin_family = AF_INET;
                 /* sin_port supplied by connection code */
                 if (procp)
@@ -622,7 +636,7 @@ long cm_SearchCellRegistry(afs_uint32 client,
 long cm_EnumerateCellRegistry(afs_uint32 client, cm_enumCellRegistryProc_t *procp, void *rockp)
 {
     HKEY hkCellServDB = 0;
-    DWORD dwType, dwSize;
+    DWORD dwSize;
     DWORD dwCells;
     DWORD dwIndex;
     LONG code;
@@ -684,6 +698,7 @@ long cm_SearchCellByDNS(char *cellNamep, char *newCellNamep, int *ttl,
     int  cellHostAddrs[AFSMAXCELLHOSTS];
     char cellHostNames[AFSMAXCELLHOSTS][MAXHOSTCHARS];
     unsigned short ipRanks[AFSMAXCELLHOSTS];
+    unsigned short ports[AFSMAXCELLHOSTS];
     int numServers;
     int i;
     struct sockaddr_in vlSockAddr;
@@ -702,13 +717,14 @@ long cm_SearchCellByDNS(char *cellNamep, char *newCellNamep, int *ttl,
          strncasecmp(cellNamep, CM_IOCTL_FILENAME_NOSLASH, strlen(CM_IOCTL_FILENAME_NOSLASH)) == 0)
        return -1;
 
-    rc = getAFSServer(cellNamep, cellHostAddrs, cellHostNames, ipRanks, &numServers, ttl);
+    rc = getAFSServer("afs3-vlserver", "udp", cellNamep, 7003,
+                      cellHostAddrs, cellHostNames, ports, ipRanks, &numServers, ttl);
     if (rc == 0 && numServers > 0) {     /* found the cell */
         for (i = 0; i < numServers; i++) {
             memcpy(&vlSockAddr.sin_addr.s_addr, &cellHostAddrs[i],
                    sizeof(long));
+            vlSockAddr.sin_port = ports[i];
             vlSockAddr.sin_family = AF_INET;
-            /* sin_port supplied by connection code */
             if (procp)
                 (*procp)(rockp, &vlSockAddr, cellHostNames[i], ipRanks[i]);
         }
index 9ad874177ce9fa6453f5f76150c124abce14080c..6bc2bdfead6feca507da4bae8e6bc0c9fee48966 100644 (file)
@@ -1062,15 +1062,22 @@ static void cm_NewRXConnection(cm_conn_t *tcp, cm_ucell_t *ucellp,
     int secIndex;
     struct rx_securityClass *secObjp;
 
-    if (serverp->type == CM_SERVER_VLDB) {
-        port = htons(7003);
+    port = serverp->addr.sin_port;
+    switch (serverp->type) {
+    case CM_SERVER_VLDB:
+        if (port == 0)
+            port = htons(7003);
         serviceID = 52;
-    }
-    else {
-        osi_assertx(serverp->type == CM_SERVER_FILE, "incorrect server type");
-        port = htons(7000);
+        break;
+    case CM_SERVER_FILE:
+        if (port == 0)
+            port = htons(7000);
         serviceID = 1;
+        break;
+    default:
+        osi_panic("unknown server type", __FILE__, __LINE__);
     }
+
     if (ucellp->flags & CM_UCELLFLAG_RXKAD) {
         secIndex = 2;
         switch (cryptall) {
@@ -1094,10 +1101,10 @@ static void cm_NewRXConnection(cm_conn_t *tcp, cm_ucell_t *ucellp,
     }
     osi_assertx(secObjp != NULL, "null rx_securityClass");
     tcp->rxconnp = rx_NewConnection(serverp->addr.sin_addr.s_addr,
-                                  port,
-                                  serviceID,
-                                  secObjp,
-                                  secIndex);
+                                    port,
+                                    serviceID,
+                                    secObjp,
+                                    secIndex);
     rx_SetConnDeadTime(tcp->rxconnp, ConnDeadtimeout);
     rx_SetConnHardDeadTime(tcp->rxconnp, HardDeadtimeout);
     rx_SetConnIdleDeadTime(tcp->rxconnp, IdleDeadtimeout);
index e5fdb13fbe2aaa7860b24b9a009f92556eceb5cc..a42cad5d92299f1db7d374c6ae5d55d39bbefb6d 100644 (file)
@@ -483,7 +483,7 @@ void printReplyBuffer_AFSDB(PDNS_HDR replyBuff)
 };
 
 void processReplyBuffer_AFSDB(SOCKET commSock, PDNS_HDR replyBuff, int *cellHostAddrs, char cellHostNames[][MAXHOSTCHARS], 
-                              unsigned short ipRanks[], int *numServers, int *ttl)
+                              unsigned short ports[], unsigned short ipRanks[], int *numServers, int *ttl)
   /*PAFS_SRV_LIST (srvList)*/
 {
   u_char *ptr = (u_char *) replyBuff;
@@ -537,6 +537,7 @@ void processReplyBuffer_AFSDB(SOCKET commSock, PDNS_HDR replyBuff, int *cellHost
          strncpy(cellHostNames[srvCount], hostName, CELL_MAXNAMELEN);
          cellHostNames[srvCount][CELL_MAXNAMELEN-1] = '\0';
       ipRanks[srvCount] = 0;
+      ports[srvCount] = htons(7003);
       srvCount++;
     }
     else {
@@ -622,8 +623,11 @@ int DNSgetAddr(SOCKET commSock, char *hostName, struct in_addr *iNet)
 }
 #endif /* DNSAPI_ENV */
 
-int getAFSServer(char *cellName, int *cellHostAddrs, char cellHostNames[][MAXHOSTCHARS], 
-                 unsigned short ipRanks[], int *numServers, int *ttl)
+int getAFSServer(const char *service, const char *protocol, const char *cellName,
+                 unsigned short afsdbPort,
+                 int *cellHostAddrs, char cellHostNames[][MAXHOSTCHARS],
+                 unsigned short ports[], unsigned short ipRanks[],
+                 int *numServers, int *ttl)
 {
 #ifndef DNSAPI_ENV
     SOCKET commSock;
@@ -637,6 +641,9 @@ int getAFSServer(char *cellName, int *cellHostAddrs, char cellHostNames[][MAXHOS
     fprintf(stderr, "getAFSServer: cell %s, cm_dnsEnabled=%d\n", cellName, cm_dnsEnabled);
 #endif
 
+    *numServers = 0;
+    *ttl = 0;
+
 #if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500)
     if (cm_dnsEnabled == -1) { /* not yet initialized, eg when called by klog */
         cm_InitDNS(1);         /* assume enabled */
@@ -644,10 +651,14 @@ int getAFSServer(char *cellName, int *cellHostAddrs, char cellHostNames[][MAXHOS
 #endif
     if (cm_dnsEnabled == 0) {  /* possibly we failed in cm_InitDNS above */
         fprintf(stderr, "DNS initialization failed, disabled\n");
-        *numServers = 0;
         return -1;
     }
   
+    if (service == NULL || protocol == NULL || cellName == NULL) {
+        fprintf(stderr, "invalid input\n");
+        return -1;
+    }
+
     sockAddr = setSockAddr(dns_addr, DNS_PORT);
   
     commSock = socket( AF_INET, SOCK_DGRAM, 0 );
@@ -655,7 +666,6 @@ int getAFSServer(char *cellName, int *cellHostAddrs, char cellHostNames[][MAXHOS
     {
         /*afsi_log("socket() failed\n");*/
         fprintf(stderr, "getAFSServer: socket() failed, errno=%d\n", errno);
-        *numServers = 0;
         return (-1);
     } 
 
@@ -668,7 +678,6 @@ int getAFSServer(char *cellName, int *cellHostAddrs, char cellHostNames[][MAXHOS
     if (rc < 0) {
         closesocket(commSock);
         fprintf(stderr,"getAFSServer: send_DNS_AFSDB_Query failed\n");
-        *numServers = 0;
         return -1;
     }
     
@@ -676,9 +685,7 @@ int getAFSServer(char *cellName, int *cellHostAddrs, char cellHostNames[][MAXHOS
   
     /*printReplyBuffer_AFSDB(pDNShdr);*/
     if (pDNShdr)
-        processReplyBuffer_AFSDB(commSock, pDNShdr, cellHostAddrs, cellHostNames, ipRanks, numServers, ttl);
-    else
-        *numServers = 0;
+        processReplyBuffer_AFSDB(commSock, pDNShdr, cellHostAddrs, cellHostNames, ports, ipRanks, numServers, ttl);
 
     closesocket(commSock);
     if (*numServers == 0)
@@ -688,35 +695,36 @@ int getAFSServer(char *cellName, int *cellHostAddrs, char cellHostNames[][MAXHOS
 #else /* DNSAPI_ENV */
     PDNS_RECORD pDnsCell, pDnsIter, pDnsVol, pDnsVolIter, pDnsCIter;
     int i;
-    struct sockaddr_in vlSockAddr;
     char query[1024];
 
+    *numServers = 0;
+    *ttl = 0;
+
+    if (service == NULL || protocol == NULL || cellName == NULL)
+        return -1;
+
 #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 */
-    StringCbCopyA(query, sizeof(query), cellName);
+    /* query the SRV _afs3-vlserver._udp records of cell */
+    StringCbPrintf(query, sizeof(query), "_%s._%s.%s", service, protocol, 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));
-
+    if (DnsQuery_A(query, DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, &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 afs3-vlserver */
-            if (pDnsIter->wType == DNS_TYPE_AFSDB && pDnsIter->Data.Afsdb.wPreference == 1) {
+            /* if we find an SRV record, we found the service */
+            if (pDnsIter->wType == DNS_TYPE_SRV) {
                 StringCbCopyA(cellHostNames[*numServers], sizeof(cellHostNames[*numServers]),
-                              pDnsIter->Data.Afsdb.pNameExchange);
-                ipRanks[*numServers] = 0;
+                              pDnsIter->Data.SRV.pNameTarget);
+                ipRanks[*numServers] = pDnsIter->Data.SRV.wPriority;
+                ports[*numServers] = pDnsIter->Data.SRV.wPort;
                 (*numServers)++;
-                
+
                 if (!*ttl) 
                     *ttl = pDnsIter->dwTtl;
                 if (*numServers == AFSMAXCELLHOSTS) 
@@ -730,7 +738,7 @@ int getAFSServer(char *cellName, int *cellHostAddrs, char cellHostNames[][MAXHOS
         /* 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 */
+                /* check if its for one of the service */
                 for (i=0;i<*numServers;i++)
                     if(cm_stricmp_utf8(pDnsIter->pName, cellHostNames[i]) == 0)
                         cellHostAddrs[i] = pDnsIter->Data.A.IpAddress;
@@ -760,7 +768,7 @@ int getAFSServer(char *cellName, int *cellHostAddrs, char cellHostNames[][MAXHOS
                             /* TODO: if the additional section is missing, then do another lookup for the CNAME */
                         }
                     }
-                    /* we are done with the afs3-vlserver lookup */
+                    /* we are done with the service lookup */
                     DnsRecordListFree(pDnsVol, DnsFreeRecordListDeep);
                 }
             }
@@ -768,22 +776,21 @@ int getAFSServer(char *cellName, int *cellHostAddrs, char cellHostNames[][MAXHOS
         DnsRecordListFree(pDnsCell, DnsFreeRecordListDeep);
     }
     else {
-        /* query the SRV _afs3-vlserver._udp records of cell */
-        StringCbPrintf(query, sizeof(query), "_afs3-vlserver._udp.%s", cellName);
+        /* query the AFSDB records of cell */
+        StringCbCopyA(query, sizeof(query), 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));
 
+        if (DnsQuery_A(query, DNS_TYPE_AFSDB, DNS_QUERY_STANDARD, NULL, &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 afs3-vlserver */
-                if (pDnsIter->wType == DNS_TYPE_SRV) {
+                /* 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) {
                     StringCbCopyA(cellHostNames[*numServers], sizeof(cellHostNames[*numServers]),
-                                   pDnsIter->Data.SRV.pNameTarget);
-                    ipRanks[*numServers] = pDnsIter->Data.SRV.wPriority;
+                                   pDnsIter->Data.Afsdb.pNameExchange);
+                    ipRanks[*numServers] = 0;
+                    ports[*numServers] = htons(afsdbPort);
                     (*numServers)++;
 
                     if (!*ttl) 
@@ -799,14 +806,14 @@ int getAFSServer(char *cellName, int *cellHostAddrs, char cellHostNames[][MAXHOS
             /* 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 */
+                    /* check if its for one of the service */
                     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
+                /* 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_A(cellHostNames[i], DNS_TYPE_A, DNS_QUERY_STANDARD, NULL, &pDnsVol, NULL) == ERROR_SUCCESS) {
@@ -829,7 +836,7 @@ int getAFSServer(char *cellName, int *cellHostAddrs, char cellHostNames[][MAXHOS
                                 /* TODO: if the additional section is missing, then do another lookup for the CNAME */
                             }
                         }
-                        /* we are done with the afs3-vlserver lookup */
+                        /* we are done with the service lookup */
                         DnsRecordListFree(pDnsVol, DnsFreeRecordListDeep);
                     }
                 }
@@ -845,42 +852,46 @@ int getAFSServer(char *cellName, int *cellHostAddrs, char cellHostNames[][MAXHOS
 #endif /* DNSAPI_ENV */
 }
 
-int getAFSServerW(cm_unichar_t *cellName, int *cellHostAddrs,
+int getAFSServerW(const cm_unichar_t *service, const cm_unichar_t *protocol, const cm_unichar_t *cellName,
+                  unsigned short afsdbPort,
+                  int *cellHostAddrs,
                   cm_unichar_t cellHostNames[][MAXHOSTCHARS], 
+                  unsigned short ports[],
                   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];
 
+    *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 */
 
-    *numServers = 0; 
-    *ttl = 0;
-
-    /* query the AFSDB records of cell */
-    StringCbCopyW(query, sizeof(query), cellName);
+    /* 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_AFSDB, DNS_QUERY_STANDARD, NULL, (PDNS_RECORD *) &pDnsCell,
+    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 AFSDB record with Preference set to 1, we found a afs3-vlserver */
-            if (pDnsIter->wType == DNS_TYPE_AFSDB && pDnsIter->Data.Afsdb.wPreference == 1) {
+        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.Afsdb.pNameExchange);
-                ipRanks[*numServers] = 0;
+                              pDnsIter->Data.SRV.pNameTarget);
+                ipRanks[*numServers] = pDnsIter->Data.SRV.wPriority;
+                ports[*numServers] = pDnsIter->Data.SRV.wPort;
                 (*numServers)++;
                 
                 if (!*ttl) 
@@ -896,15 +907,15 @@ int getAFSServerW(cm_unichar_t *cellName, int *cellHostAddrs,
         /* 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 */
+                /* 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 afs3-vlserver hostname
-               in a separate query. */
+            /* 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) {
@@ -927,7 +938,7 @@ int getAFSServerW(cm_unichar_t *cellName, int *cellHostAddrs,
                             /* TODO: if the additional section is missing, then do another lookup for the CNAME */
                         }
                     }
-                    /* we are done with the afs3-vlserver lookup */
+                    /* we are done with the service lookup */
                     DnsRecordListFree((PDNS_RECORD) pDnsVol, DnsFreeRecordListDeep);
                 }
             }
@@ -935,23 +946,22 @@ int getAFSServerW(cm_unichar_t *cellName, int *cellHostAddrs,
         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);
+        /* 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_SRV, DNS_QUERY_STANDARD, NULL, (PDNS_RECORD *) &pDnsCell,
-                        NULL) == ERROR_SUCCESS) {
-            memset((void*) &vlSockAddr, 0, sizeof(vlSockAddr));
-
+        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 SRV record, we found a afs3-vlserver */
-                if (pDnsIter->wType == DNS_TYPE_SRV) {
+            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.SRV.pNameTarget);
-                    ipRanks[*numServers] = pDnsIter->Data.SRV.wPriority;
+                                  pDnsIter->Data.Afsdb.pNameExchange);
+                    ipRanks[*numServers] = 0;
+                    ports[*numServers] = htons(afsdbPort);
                     (*numServers)++;
                 
                     if (!*ttl) 
@@ -967,18 +977,18 @@ int getAFSServerW(cm_unichar_t *cellName, int *cellHostAddrs,
             /* 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 */
+                    /* 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 afs3-vlserver hostname
+                /* 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) {
+                                   (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) {
@@ -998,7 +1008,7 @@ int getAFSServerW(cm_unichar_t *cellName, int *cellHostAddrs,
                                 /* TODO: if the additional section is missing, then do another lookup for the CNAME */
                             }
                         }
-                        /* we are done with the afs3-vlserver lookup */
+                        /* we are done with the service lookup */
                         DnsRecordListFree((PDNS_RECORD) pDnsVol, DnsFreeRecordListDeep);
                     }
                 }
index 410ed8cc825982b27535f9470d48356840c8a9ee..fb907ba63ec8e45443d211d3d6cfdea8c039526f 100644 (file)
 
 /* this function will continue to return cell server
    names for the given cell, ending in null */
-int getAFSServer(char *cellname, int *cellHostAddrs, char cellHostNames[][MAXHOSTCHARS], 
-                 unsigned short ipRanks[], int *numServers, int *ttl);
+int getAFSServer(const char *service, const char *protocol, const char *cellname,
+                 unsigned short afsdbPort,
+                 int *cellHostAddrs, char cellHostNames[][MAXHOSTCHARS],
+                 unsigned short ports[], unsigned short ipRanks[], int *numServers, int *ttl);
 
 /* Same as above, but using cm_unichar_t.  Note that this functon will
    only be defined for DNSAPI_ENV. */
-int getAFSServerW(cm_unichar_t *cellName, int *cellHostAddrs,
+int getAFSServerW(const cm_unichar_t *service, const cm_unichar_t *protocol, const cm_unichar_t *cellName,
+                  unsigned short afsdbPort,
+                  int *cellHostAddrs,
                   cm_unichar_t cellHostNames[][MAXHOSTCHARS], 
+                  unsigned short ports[],
                   unsigned short ipRanks[],
                   int *numServers, int *ttl);
 
index 66fce80f5a72193699775e10c81a645a2e9fa2c9..0768079380aca5d09fe2a8fa8f43762d131aa1e2 100644 (file)
@@ -1748,6 +1748,14 @@ cm_IoctlSetSPrefs(struct cm_ioctl *ioctlp, struct cm_user *userp)
         srvin          = &(spin->servers[i]);
         rank           = srvin->rank + (rand() & 0x000f);
         tmp.sin_addr   = srvin->host;
+        switch (type) {
+        case CM_SERVER_VLDB:
+            tmp.sin_port = htons(7003);
+            break;
+        case CM_SERVER_FILE:
+            tmp.sin_port = htons(7000);
+            break;
+        }
         tmp.sin_family = AF_INET;
 
         tsp = cm_FindServer(&tmp, type);
index f1f99982991cda63a0ef761893860dc188ec850c..b83eb4eb18b8d317c0ec26721d96fcaea6814b61 100644 (file)
@@ -971,7 +971,8 @@ cm_server_t *cm_FindServer(struct sockaddr_in *addrp, int type)
     lock_ObtainRead(&cm_serverLock);
     for (tsp = cm_allServersp; tsp; tsp=tsp->allNextp) {
         if (tsp->type == type &&
-            tsp->addr.sin_addr.s_addr == addrp->sin_addr.s_addr) 
+            tsp->addr.sin_addr.s_addr == addrp->sin_addr.s_addr &&
+            (tsp->addr.sin_port == addrp->sin_port || tsp->addr.sin_port == 0))
             break;
     }       
 
index b449295f6e4db54bc6efab836ee23919dc98dbd3..4e150519edf132730ed6374a70b9807a5d0e861a 100644 (file)
@@ -500,6 +500,7 @@ long cm_UpdateVolumeLocation(struct cm_cell *cellp, cm_user_t *userp, cm_req_t *
             tflags = serverFlags[i];
             if (tflags & VLSF_DONTUSE) 
                 continue;
+            tsockAddr.sin_port = htons(7000);
             tsockAddr.sin_family = AF_INET;
             tempAddr = htonl(serverNumber[i]);
             tsockAddr.sin_addr.s_addr = tempAddr;
index ec944696310fe2f53c90ccce7ca7254b1a8ab5a9..d2351e02450d61f44b3fcf8ed7d8fa2c66283e56 100644 (file)
@@ -1125,25 +1125,52 @@ int
 afsconf_GetAfsdbInfo(char *acellName, char *aservice,
                     struct afsconf_cell *acellInfo)
 {
-    register afs_int32 i;
-    int tservice;
+    afs_int32 i;
+    int tservice = afsconf_FindService(aservice);
+    const char *ianaName = afsconf_FindIANAName(aservice);
     struct afsconf_entry DNSce;
     afs_int32 cellHostAddrs[AFSMAXCELLHOSTS];
     char cellHostNames[AFSMAXCELLHOSTS][MAXHOSTCHARS];
     unsigned short ipRanks[AFSMAXCELLHOSTS];
+    unsigned short ports[AFSMAXCELLHOSTS];
     int numServers;
     int rc;
     int ttl;
 
+    if (tservice < 0) {
+        if (aservice)
+            return AFSCONF_NOTFOUND;
+        else
+            tservice = 0;       /* port will be assigned by caller */
+    }
+
+    if (ianaName == NULL)
+        ianaName = "afs3-vlserver";
+
     DNSce.cellInfo.numServers = 0;
     DNSce.next = NULL;
-    rc = getAFSServer(acellName, cellHostAddrs, cellHostNames, ipRanks, &numServers,
+
+    rc = getAFSServer(ianaName, "udp", acellName, tservice,
+                      cellHostAddrs, cellHostNames, ports, ipRanks, &numServers,
                      &ttl);
     /* ignore the ttl here since this code is only called by transitory programs
      * like klog, etc. */
-    if (rc < 0)
-       return -1;
-    if (numServers == 0)
+
+    /* If we couldn't find an entry for the requested service
+     * and that service happens to be the prservice or kaservice
+     * then fallback to searching for afs3-vlserver and assigning
+     * the port number here. */
+    if (rc < 0 && tservice == 7002 || tservice == 7004) {
+        rc = getAFSServer("afs3-vlserver", "udp", acellName, tservice,
+                           cellHostAddrs, cellHostNames, ports, ipRanks, &numServers,
+                           &ttl);
+        if (rc >= 0) {
+            for (i = 0; i < numServers; i++)
+                ports[i] = tservice;
+        }
+    }
+
+    if (rc < 0 || numServers == 0)
        return -1;
 
     for (i = 0; i < numServers; i++) {
@@ -1151,23 +1178,14 @@ afsconf_GetAfsdbInfo(char *acellName, char *aservice,
               sizeof(long));
        memcpy(acellInfo->hostName[i], cellHostNames[i], MAXHOSTCHARS);
        acellInfo->hostAddr[i].sin_family = AF_INET;
-
-       /* sin_port supplied by connection code */
+        if (aservice)
+            acellInfo->hostAddr[i].sin_port = ports[i];
+        else
+            acellInfo->hostAddr[i].sin_port = 0;
     }
 
     acellInfo->numServers = numServers;
     strlcpy(acellInfo->name, acellName, sizeof acellInfo->name);
-    if (aservice) {
-       LOCK_GLOBAL_MUTEX;
-       tservice = afsconf_FindService(aservice);
-       UNLOCK_GLOBAL_MUTEX;
-       if (tservice < 0) {
-           return AFSCONF_NOTFOUND;    /* service not found */
-       }
-       for (i = 0; i < acellInfo->numServers; i++) {
-           acellInfo->hostAddr[i].sin_port = tservice;
-       }
-    }
     acellInfo->linkedCell = NULL;      /* no linked cell */
     acellInfo->flags = 0;
     return 0;