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];
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);
/* 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++;
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;
}
if (conns[i] != connSuccess)
rx_DestroyConnection(conns[i]);
- free(addr);
+ free(interfaces);
free(conns);
if (connSuccess)
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];
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);
}
/* 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++;
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
/* 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++;
}
}
if (conns[i] != connSuccess)
rx_DestroyConnection(conns[i]);
- free(addr);
+ free(interfaces);
free(conns);
if (connSuccess)
/* 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);
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)
/* 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) {
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)
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;
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);
(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: ");
/*
* 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;
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) {
}
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++;
}
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);
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;
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"));
}