From bc0c9027929f367ac6484e10a900ad28d22fadbe Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Fri, 16 Dec 2005 13:29:38 +0000 Subject: [PATCH] STABLE14-viced-multiple-ports-per-client-20051208 this patch replaces the single address in the Interface structure with an AddrPort structure. This enables the servers to send messages to the correct port if the port on the Interface does not match the port stored in the client itself. (cherry picked from commit 71f9628a437e0ac7b9b9754d71c06ca5c3408061) --- src/viced/callback.c | 49 +++++----- src/viced/host.c | 220 +++++++++++++++++++++++-------------------- src/viced/host.h | 12 ++- 3 files changed, 156 insertions(+), 125 deletions(-) diff --git a/src/viced/callback.c b/src/viced/callback.c index 778986e63..7dd36bc49 100644 --- a/src/viced/callback.c +++ b/src/viced/callback.c @@ -1974,7 +1974,7 @@ MultiBreakCallBackAlternateAddress_r(struct host *host, int i, j; struct rx_connection **conns; struct rx_connection *connSuccess = 0; - afs_int32 *addr; + struct AddrPort *interfaces; static struct rx_securityClass *sc = 0; static struct AFSCBs tc = { 0, 0 }; char hoststr[16]; @@ -1994,9 +1994,9 @@ MultiBreakCallBackAlternateAddress_r(struct host *host, sc = rxnull_NewClientSecurityObject(); i = host->interface->numberOfInterfaces; - addr = calloc(i, sizeof(afs_int32)); + interfaces = calloc(i, sizeof(struct AddrPort)); conns = calloc(i, sizeof(struct rx_connection *)); - if (!addr || !conns) { + if (!interfaces || !conns) { ViceLog(0, ("Failed malloc in MultiBreakCallBackAlternateAddress_r\n")); assert(0); @@ -2005,12 +2005,14 @@ MultiBreakCallBackAlternateAddress_r(struct host *host, /* initialize alternate rx connections */ for (i = 0, j = 0; i < host->interface->numberOfInterfaces; i++) { /* this is the current primary address */ - if (host->host == host->interface->addr[i]) + if (host->host == host->interface->interface[i].addr && + host->port == host->interface->interface[i].port) continue; - addr[j] = host->interface->addr[i]; + interfaces[j] = host->interface->interface[i]; conns[j] = - rx_NewConnection(host->interface->addr[i], host->port, 1, sc, 0); + rx_NewConnection(interfaces[j].addr, + interfaces[j].port, 1, sc, 0); rx_SetConnDeadTime(conns[j], 2); rx_SetConnHardDeadTime(conns[j], AFS_HARDDEADTIME); j++; @@ -2029,13 +2031,14 @@ MultiBreakCallBackAlternateAddress_r(struct host *host, if (host->callback_rxcon) rx_DestroyConnection(host->callback_rxcon); host->callback_rxcon = conns[multi_i]; - host->host = addr[multi_i]; + host->host = interfaces[multi_i].addr; + host->port = interfaces[multi_i].port; connSuccess = conns[multi_i]; rx_SetConnDeadTime(host->callback_rxcon, 50); rx_SetConnHardDeadTime(host->callback_rxcon, AFS_HARDDEADTIME); ViceLog(125, ("multibreakcall success with addr %s\n", - afs_inet_ntoa_r(addr[multi_i], hoststr))); + afs_inet_ntoa_r(interfaces[multi_i].addr, hoststr))); H_UNLOCK; multi_Abort; } @@ -2047,7 +2050,7 @@ MultiBreakCallBackAlternateAddress_r(struct host *host, if (conns[i] != connSuccess) rx_DestroyConnection(conns[i]); - free(addr); + free(interfaces); free(conns); if (connSuccess) @@ -2067,7 +2070,7 @@ MultiProbeAlternateAddress_r(struct host *host) int i, j; struct rx_connection **conns; struct rx_connection *connSuccess = 0; - afs_int32 *addr; + struct AddrPort *interfaces; static struct rx_securityClass *sc = 0; char hoststr[16]; @@ -2086,9 +2089,9 @@ MultiProbeAlternateAddress_r(struct host *host) sc = rxnull_NewClientSecurityObject(); i = host->interface->numberOfInterfaces; - addr = calloc(i, sizeof(afs_int32)); + interfaces = calloc(i, sizeof(struct AddrPort)); conns = calloc(i, sizeof(struct rx_connection *)); - if (!addr || !conns) { + if (!interfaces || !conns) { ViceLog(0, ("Failed malloc in MultiProbeAlternateAddress_r\n")); assert(0); } @@ -2096,12 +2099,14 @@ MultiProbeAlternateAddress_r(struct host *host) /* initialize alternate rx connections */ for (i = 0, j = 0; i < host->interface->numberOfInterfaces; i++) { /* this is the current primary address */ - if (host->host == host->interface->addr[i]) + if (host->host == host->interface->interface[i].addr && + host->port == host->interface->interface[i].port) continue; - addr[j] = host->interface->addr[i]; + interfaces[j] = host->interface->interface[i]; conns[j] = - rx_NewConnection(host->interface->addr[i], host->port, 1, sc, 0); + rx_NewConnection(interfaces[i].addr, + interfaces[i].port, 1, sc, 0); rx_SetConnDeadTime(conns[j], 2); rx_SetConnHardDeadTime(conns[j], AFS_HARDDEADTIME); j++; @@ -2120,19 +2125,20 @@ MultiProbeAlternateAddress_r(struct host *host) if (host->callback_rxcon) rx_DestroyConnection(host->callback_rxcon); host->callback_rxcon = conns[multi_i]; - host->host = addr[multi_i]; + host->host = interfaces[multi_i].addr; + host->port = interfaces[multi_i].port; connSuccess = conns[multi_i]; rx_SetConnDeadTime(host->callback_rxcon, 50); rx_SetConnHardDeadTime(host->callback_rxcon, AFS_HARDDEADTIME); ViceLog(125, ("multiprobe success with addr %s\n", - afs_inet_ntoa_r(addr[multi_i], hoststr))); + afs_inet_ntoa_r(interfaces[multi_i].addr, hoststr))); H_UNLOCK; multi_Abort; } else { ViceLog(125, ("multiprobe failure with addr %s\n", - afs_inet_ntoa_r(addr[multi_i], hoststr))); + afs_inet_ntoa_r(interfaces[multi_i].addr, hoststr))); /* This is less than desirable but its the best we can do. * The AFS Cache Manager will return either 0 for a Uuid @@ -2147,8 +2153,9 @@ MultiProbeAlternateAddress_r(struct host *host) /* remove the current alternate address from this host */ H_LOCK; for (i = 0, j = 0; i < host->interface->numberOfInterfaces; i++) { - if (addr[multi_i] != host->interface->addr[i]) { - host->interface->addr[j] = host->interface->addr[i]; + if (interfaces[multi_i].addr != host->interface->interface[i].addr && + interfaces[multi_i].port != host->interface->interface[i].port) { + host->interface->interface[j] = host->interface->interface[i]; j++; } } @@ -2164,7 +2171,7 @@ MultiProbeAlternateAddress_r(struct host *host) if (conns[i] != connSuccess) rx_DestroyConnection(conns[i]); - free(addr); + free(interfaces); free(conns); if (connSuccess) diff --git a/src/viced/host.c b/src/viced/host.c index 5c9cc8cdd..c768188ee 100644 --- a/src/viced/host.c +++ b/src/viced/host.c @@ -613,20 +613,20 @@ h_Alloc_r(register struct rx_connection *r_con) /* Note: host should be released by caller if 0 == *heldp and non-null */ /* hostaddr and hport are in network order */ struct host * -h_Lookup_r(afs_uint32 hostaddr, afs_uint32 hport, int *heldp) +h_Lookup_r(afs_uint32 haddr, afs_uint32 hport, int *heldp) { register afs_int32 now; register struct host *host = 0; register struct h_hashChain *chain; - register index = h_HashIndex(hostaddr); + register index = h_HashIndex(haddr); extern int hostaclRefresh; restart: for (chain = hostHashTable[index]; chain; chain = chain->next) { host = chain->hostPtr; assert(host); - if (!(host->hostFlags & HOSTDELETED) && chain->addr == hostaddr - && host->port == hport) { + if (!(host->hostFlags & HOSTDELETED) && chain->addr == haddr + && chain->port == hport) { *heldp = h_Held_r(host); if (!*heldp) h_Hold_r(host); @@ -746,7 +746,7 @@ h_TossStuff_r(register struct host *host) register struct h_hashChain **hp, *th; register struct rx_connection *rxconn; afsUUID *uuidp; - afs_uint32 hostAddr; + struct AddrPort hostAddrPort; int i; if (host->Console & 1) @@ -800,8 +800,9 @@ h_TossStuff_r(register struct host *host) /* delete all hash entries for alternate addresses */ assert(host->interface->numberOfInterfaces > 0); for (i = 0; i < host->interface->numberOfInterfaces; i++) { - hostAddr = host->interface->addr[i]; - for (hp = &hostHashTable[h_HashIndex(hostAddr)]; (th = *hp); + hostAddrPort = host->interface->interface[i]; + + for (hp = &hostHashTable[h_HashIndex(hostAddrPort.addr)]; (th = *hp); hp = &th->next) { assert(th->hostPtr); if (th->hostPtr == host) { @@ -935,6 +936,88 @@ hashInsertUuid_r(struct afsUUID *uuid, struct host *host) hostUuidHashTable[index] = chain; } + +/* inserts a new HashChain structure corresponding to this address */ +void +hashInsert_r(afs_uint32 addr, afs_uint16 port, struct host *host) +{ + int index; + struct h_hashChain *chain; + + /* hash into proper bucket */ + index = h_HashIndex(addr); + + /* insert into beginning of list for this bucket */ + chain = (struct h_hashChain *)malloc(sizeof(struct h_hashChain)); + if (!chain) { + ViceLog(0, ("Failed malloc in hashInsert_r\n")); + assert(0); + } + chain->hostPtr = host; + chain->next = hostHashTable[index]; + chain->addr = addr; + chain->port = port; + hostHashTable[index] = chain; + +} + +/* + * This is called with host locked and held. At this point, the + * hostHashTable should not be having entries for the alternate + * interfaces. This function has to insert these entries in the + * hostHashTable. + * + * All addresses are in network byte order. + */ +int +addInterfaceAddr_r(struct host *host, afs_uint32 addr, afs_uint16 port) +{ + int i; + int number; + int found; + struct Interface *interface; + + assert(host); + assert(host->interface); + + ViceLog(125, ("addInterfaceAddr : host %x addr %x:%d\n", host->host, addr, ntohs(port))); + + /* + * Make sure this address is on the list of known addresses + * for this host. + */ + number = host->interface->numberOfInterfaces; + for (i = 0, found = 0; i < number && !found; i++) { + if (host->interface->interface[i].addr == addr && + host->interface->interface[i].port == port) + found = 1; + } + if (!found) { + interface = (struct Interface *) + malloc(sizeof(struct Interface) + (sizeof(struct AddrPort) * number)); + if (!interface) { + ViceLog(0, ("Failed malloc in addInterfaceAddr_r\n")); + assert(0); + } + interface->numberOfInterfaces = number + 1; + interface->uuid = host->interface->uuid; + for (i = 0; i < number; i++) + interface->interface[i] = host->interface->interface[i]; + interface->interface[number].addr = addr; + interface->interface[number].port = port; + free(host->interface); + host->interface = interface; + } + + /* + * Create a hash table entry for this address + */ + hashInsert_r(addr, port, host); + + return 0; +} + + /* Host is returned held */ struct host * h_GetHost_r(struct rx_connection *tcon) @@ -947,7 +1030,7 @@ h_GetHost_r(struct rx_connection *tcon) int interfValid = 0; struct Identity *identP = NULL; afs_int32 haddr; - afs_int32 hport; + afs_int16 hport; char hoststr[16], hoststr2[16]; Capabilities caps; struct rx_connection *cb_conn = NULL; @@ -1210,7 +1293,7 @@ h_GetHost_r(struct rx_connection *tcon) ntohs(host->port), afs_inet_ntoa_r(oldHost->host, hoststr2), ntohs(oldHost->port))); - addInterfaceAddr_r(oldHost, haddr); + addInterfaceAddr_r(oldHost, haddr, hport); host->hostFlags |= HOSTDELETED; h_Unlock_r(host); h_Release_r(host); @@ -1843,7 +1926,8 @@ h_DumpHost(register struct host *host, int held, StreamHandle_t * file) (void)STREAM_WRITE(tmpStr, strlen(tmpStr), 1, file); if (host->interface) for (i = 0; i < host->interface->numberOfInterfaces; i++) { - sprintf(tmpStr, " %x", host->interface->addr[i]); + sprintf(tmpStr, " %x:%d", host->interface->interface[i].addr, + ntohs(host->interface->interface[i].port)); (void)STREAM_WRITE(tmpStr, strlen(tmpStr), 1, file); } sprintf(tmpStr, "] holds: "); @@ -2224,18 +2308,19 @@ h_CheckHosts() /* * This is called with host locked and held. At this point, the - * hostHashTable should not be having entries for the alternate + * hostHashTable should not have any entries for the alternate * interfaces. This function has to insert these entries in the * hostHashTable. * - * The addresses in the ineterfaceAddr list are in host byte order. + * The addresses in the interfaceAddr list are in host byte order. */ int initInterfaceAddr_r(struct host *host, struct interfaceAddr *interf) { int i, j; int number, count; - afs_int32 myHost; + afs_uint32 myAddr; + afs_uint16 myPort; int found; struct Interface *interface; @@ -2247,7 +2332,8 @@ initInterfaceAddr_r(struct host *host, struct interfaceAddr *interf) interf->numberOfInterfaces)); number = interf->numberOfInterfaces; - myHost = host->host; /* current interface address */ + myAddr = host->host; /* current interface address */ + myPort = host->port; /* current port */ /* validation checks */ if (number < 0 || number > AFS_MAX_INTERFACE_ADDR) { @@ -2268,7 +2354,7 @@ initInterfaceAddr_r(struct host *host, struct interfaceAddr *interf) } if (j == count) { interf->addr_in[count] = interf->addr_in[i]; - if (interf->addr_in[count] == myHost) + if (interf->addr_in[count] == myAddr) found = 1; count++; } @@ -2280,7 +2366,7 @@ initInterfaceAddr_r(struct host *host, struct interfaceAddr *interf) if (found) { interface = (struct Interface *) malloc(sizeof(struct Interface) + - (sizeof(afs_int32) * (count - 1))); + (sizeof(struct AddrPort) * (count - 1))); if (!interface) { ViceLog(0, ("Failed malloc in initInterfaceAddr_r\n")); assert(0); @@ -2288,113 +2374,44 @@ initInterfaceAddr_r(struct host *host, struct interfaceAddr *interf) interface->numberOfInterfaces = count; } else { interface = (struct Interface *) - malloc(sizeof(struct Interface) + (sizeof(afs_int32) * count)); + malloc(sizeof(struct Interface) + (sizeof(struct AddrPort) * count)); assert(interface); interface->numberOfInterfaces = count + 1; - interface->addr[count] = myHost; + interface->interface[count].addr = myAddr; + interface->interface[count].port = myPort; } interface->uuid = interf->uuid; - for (i = 0; i < count; i++) - interface->addr[i] = interf->addr_in[i]; + for (i = 0; i < count; i++) { + interface->interface[i].addr = interf->addr_in[i]; + /* We store the port as 7001 because the addresses reported by + * TellMeAboutYourself and WhoAreYou RPCs are only valid if they + * are coming from fully connected hosts (no NAT/PATs) + */ + interface->interface[i].port = htons(7001); + } assert(!host->interface); host->interface = interface; for (i = 0; i < host->interface->numberOfInterfaces; i++) { - ViceLog(125, ("--- alt address %x\n", host->interface->addr[i])); - } - - return 0; -} - -/* inserts a new HashChain structure corresponding to this address */ -void -hashInsert_r(afs_int32 addr, struct host *host) -{ - int index; - struct h_hashChain *chain; - - /* hash into proper bucket */ - index = h_HashIndex(addr); - - /* insert into beginning of list for this bucket */ - chain = (struct h_hashChain *)malloc(sizeof(struct h_hashChain)); - if (!chain) { - ViceLog(0, ("Failed malloc in hashInsert_r\n")); - assert(0); - } - chain->hostPtr = host; - chain->next = hostHashTable[index]; - chain->addr = addr; - hostHashTable[index] = chain; - -} - -/* - * This is called with host locked and held. At this point, the - * hostHashTable should not be having entries for the alternate - * interfaces. This function has to insert these entries in the - * hostHashTable. - * - * All addresses are in network byte order. - */ -int -addInterfaceAddr_r(struct host *host, afs_int32 addr) -{ - int i; - int number; - int found; - struct Interface *interface; - - assert(host); - assert(host->interface); - - ViceLog(125, ("addInterfaceAddr : host %x addr %d\n", host->host, addr)); - - /* - * Make sure this address is on the list of known addresses - * for this host. - */ - number = host->interface->numberOfInterfaces; - for (i = 0, found = 0; i < number && !found; i++) { - if (host->interface->addr[i] == addr) - found = 1; - } - if (!found) { - interface = (struct Interface *) - malloc(sizeof(struct Interface) + (sizeof(afs_int32) * number)); - if (!interface) { - ViceLog(0, ("Failed malloc in addInterfaceAddr_r\n")); - assert(0); - } - interface->numberOfInterfaces = number + 1; - interface->uuid = host->interface->uuid; - for (i = 0; i < number; i++) - interface->addr[i] = host->interface->addr[i]; - interface->addr[number] = addr; - free(host->interface); - host->interface = interface; + ViceLog(125, ("--- alt address %x:%d\n", host->interface->interface[i].addr, + ntohs(host->interface->interface[i].port))); } - /* - * Create a hash table entry for this address - */ - hashInsert_r(addr, host); - return 0; } /* deleted a HashChain structure for this address and host */ /* returns 1 on success */ int -hashDelete_r(afs_int32 addr, struct host *host) +hashDelete_r(afs_uint32 addr, afs_uint16 port, struct host *host) { int flag; register struct h_hashChain **hp, *th; for (hp = &hostHashTable[h_HashIndex(addr)]; (th = *hp);) { assert(th->hostPtr); - if (th->hostPtr == host && th->addr == addr) { + if (th->hostPtr == host && th->addr == addr && th->port == port) { *hp = th->next; free(th); flag = 1; @@ -2420,7 +2437,8 @@ printInterfaceAddr(struct host *host, int level) number = host->interface->numberOfInterfaces; assert(number > 0); for (i = 0; i < number; i++) - ViceLog(level, ("%x ", host->interface->addr[i])); + ViceLog(level, ("%x:%d ", host->interface->interface[i].addr, + ntohs(host->interface->interface[i].port))); } ViceLog(level, ("\n")); } diff --git a/src/viced/host.h b/src/viced/host.h index 4bc00d39f..a095d729f 100644 --- a/src/viced/host.h +++ b/src/viced/host.h @@ -48,10 +48,15 @@ struct Identity { afsUUID uuid; }; +struct AddrPort { + afs_uint32 addr; /* in network byte order */ + afs_uint16 port; /* in network byte order */ +}; + struct Interface { - int numberOfInterfaces; afsUUID uuid; - afs_int32 addr[1]; /* there are actually more than one here */ + int numberOfInterfaces; + struct AddrPort interface[1];/* there are actually more than one here */ /* in network byte order */ }; struct host { @@ -99,7 +104,8 @@ struct host { struct h_hashChain { struct host *hostPtr; struct h_hashChain *next; - afs_int32 addr; + afs_uint32 addr; + afs_uint16 port; }; struct client { -- 2.39.5