From e249aace420e20996fef8ace2b5051d5bbdcd809 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Tue, 6 Oct 2009 14:46:09 -0400 Subject: [PATCH 1/1] Permit DNS SRV record lookups to be used by the Windows afsconf_GetAfsdbInfo 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 Tested-by: Jeffrey Altman --- src/WINNT/afsd/afsd_init.c | 2 + src/WINNT/afsd/cm_callback.c | 1 + src/WINNT/afsd/cm_config.c | 26 ++++++-- src/WINNT/afsd/cm_conn.c | 27 +++++--- src/WINNT/afsd/cm_dns.c | 152 +++++++++++++++++++++++-------------------- src/WINNT/afsd/cm_dns.h | 11 +++- src/WINNT/afsd/cm_ioctl.c | 8 +++ src/WINNT/afsd/cm_server.c | 3 +- src/WINNT/afsd/cm_volume.c | 1 + src/auth/cellconfig.c | 56 ++++++++++------ 10 files changed, 178 insertions(+), 109 deletions(-) diff --git a/src/WINNT/afsd/afsd_init.c b/src/WINNT/afsd/afsd_init.c index ab38b55..d9f85f3 100644 --- a/src/WINNT/afsd/afsd_init.c +++ b/src/WINNT/afsd/afsd_init.c @@ -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); diff --git a/src/WINNT/afsd/cm_callback.c b/src/WINNT/afsd/cm_callback.c index 006cedb..d5e36da 100644 --- a/src/WINNT/afsd/cm_callback.c +++ b/src/WINNT/afsd/cm_callback.c @@ -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); diff --git a/src/WINNT/afsd/cm_config.c b/src/WINNT/afsd/cm_config.c index b54216c..534bbde 100644 --- a/src/WINNT/afsd/cm_config.c +++ b/src/WINNT/afsd/cm_config.c @@ -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" - * "ptserver" DWORD ... + * "ptserver" DWORD "7002" * * 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]); } diff --git a/src/WINNT/afsd/cm_conn.c b/src/WINNT/afsd/cm_conn.c index 9ad8741..6bc2bdf 100644 --- a/src/WINNT/afsd/cm_conn.c +++ b/src/WINNT/afsd/cm_conn.c @@ -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); diff --git a/src/WINNT/afsd/cm_dns.c b/src/WINNT/afsd/cm_dns.c index e5fdb13..a42cad5 100644 --- a/src/WINNT/afsd/cm_dns.c +++ b/src/WINNT/afsd/cm_dns.c @@ -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); } } diff --git a/src/WINNT/afsd/cm_dns.h b/src/WINNT/afsd/cm_dns.h index 410ed8c..fb907ba 100644 --- a/src/WINNT/afsd/cm_dns.h +++ b/src/WINNT/afsd/cm_dns.h @@ -13,13 +13,18 @@ /* 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); diff --git a/src/WINNT/afsd/cm_ioctl.c b/src/WINNT/afsd/cm_ioctl.c index 66fce80..0768079 100644 --- a/src/WINNT/afsd/cm_ioctl.c +++ b/src/WINNT/afsd/cm_ioctl.c @@ -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); diff --git a/src/WINNT/afsd/cm_server.c b/src/WINNT/afsd/cm_server.c index f1f9998..b83eb4e 100644 --- a/src/WINNT/afsd/cm_server.c +++ b/src/WINNT/afsd/cm_server.c @@ -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; } diff --git a/src/WINNT/afsd/cm_volume.c b/src/WINNT/afsd/cm_volume.c index b449295..4e15051 100644 --- a/src/WINNT/afsd/cm_volume.c +++ b/src/WINNT/afsd/cm_volume.c @@ -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; diff --git a/src/auth/cellconfig.c b/src/auth/cellconfig.c index ec94469..d2351e0 100644 --- a/src/auth/cellconfig.c +++ b/src/auth/cellconfig.c @@ -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; -- 1.9.4