openafs (1.4.12.1+dfsg-4) src/viced/host.c

Summary

 src/viced/host.c |  521 ++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 308 insertions(+), 213 deletions(-)

    
download this patch

Patch contents

--- openafs-1.4.12.1+dfsg.orig/src/viced/host.c
+++ openafs-1.4.12.1+dfsg/src/viced/host.c
@@ -10,7 +10,6 @@
 #include <afsconfig.h>
 #include <afs/param.h>
 
-
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
@@ -503,15 +502,17 @@
 	if (!h_OtherHolds_r(host)) {
 	    /* must avoid masking this until after h_OtherHolds_r runs
 	     * but it should be run before h_TossStuff_r */
-	    (host)->holds[h_holdSlot()] &= ~h_holdbit();
+	    h_Decrement_r(host);
 	    if ((host->hostFlags & HOSTDELETED)
 		|| (host->hostFlags & CLIENTDELETED)) {
 		h_TossStuff_r(host);
 	    }
-	} else
-	    (host)->holds[h_holdSlot()] &= ~h_holdbit();
-    } else
-	(host)->holds[h_holdSlot()] &= ~h_holdbit();
+	} else {
+	    h_Decrement_r(host);
+	}
+    } else {
+	h_Decrement_r(host);
+    }
 
     return 0;
 }
@@ -766,7 +767,7 @@
     host->host = rxr_HostOf(r_con);
     host->port = rxr_PortOf(r_con);
 
-    hashInsert_r(host->host, host->port, host);
+    h_AddHostToAddrHashTable_r(host->host, host->port, host);
 
     if (consolePort == 0) {	/* find the portal number for console */
 #if	defined(AFS_OSF_ENV)
@@ -887,12 +888,10 @@
 	assert(host);
 	if (!(host->hostFlags & HOSTDELETED) && host->interface
 	    && afs_uuid_equal(&host->interface->uuid, uuidp)) {
-	    break;
+	    return host;
 	}
-	host = NULL;
     }
-    return host;
-
+    return NULL;
 }				/*h_Lookup */
 
 
@@ -913,23 +912,39 @@
 {
     register struct client **cp, *client;
     int i;
+    int code;
 
-    /* if somebody still has this host held */
-    for (i = 0; (i < h_maxSlots) && (!(host)->holds[i]); i++);
-    if (i != h_maxSlots)
-	return;
+    /* make sure host doesn't go away over h_NBLock_r */
+    h_Hold_r(host);
+
+    code = h_NBLock_r(host);
+
+    /* don't use h_Release_r, since that may call h_TossStuff_r again */
+    h_Decrement_r(host);
 
     /* if somebody still has this host locked */
-    if (h_NBLock_r(host) != 0) {
+    if (code != 0) {
 	char hoststr[16];
 	ViceLog(0,
-		("Warning:  h_TossStuff_r failed; Host %s:%d was locked.\n",
-		 afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
+		("Warning:  h_TossStuff_r failed; Host 0x%lx (%s:%d) was locked.\n",
+		 (unsigned long) host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
 	return;
     } else {
 	h_Unlock_r(host);
     }
 
+    /* if somebody still has this host held */
+    /* we must check this _after_ h_NBLock_r, since h_NBLock_r can drop and
+     * reacquire H_LOCK */
+    for (i = 0; (i < h_maxSlots) && (!(host)->holds[i]); i++);
+    if (i != h_maxSlots) {
+	char hoststr[16];
+	ViceLog(0,
+		("Warning:  h_TossStuff_r failed; Host 0x%lx (%s:%d) was held.\n",
+		 (unsigned long) host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
+	return;
+    }
+
     /* ASSUMPTION: rxi_FreeConnection() does not yield */
     for (cp = &host->FirstClient; (client = *cp);) {
 	if ((host->hostFlags & HOSTDELETED) || client->deleted) {
@@ -938,8 +953,8 @@
 	    if (code < 0) {
 		char hoststr[16];
 		ViceLog(0,
-			("Warning: h_TossStuff_r failed: Host %s:%d client %x was locked.\n",
-			 afs_inet_ntoa_r(host->host, hoststr),
+			("Warning: h_TossStuff_r failed: Host 0x%lx (%s:%d) client %x was locked.\n",
+			 (unsigned long) host, afs_inet_ntoa_r(host->host, hoststr),
 			 ntohs(host->port), client));
 		return;
 	    }
@@ -947,8 +962,8 @@
 	    if (client->refCount) {
 		char hoststr[16];
 		ViceLog(0,
-			("Warning: h_TossStuff_r failed: Host %s:%d client %x refcount %d.\n",
-			 afs_inet_ntoa_r(host->host, hoststr),
+			("Warning: h_TossStuff_r failed: Host 0x%lx (%s:%d) client %x refcount %d.\n",
+			 (unsigned long) host, afs_inet_ntoa_r(host->host, hoststr),
 			 ntohs(host->port), client, client->refCount));
 		/* This is the same thing we do if the host is locked */
 		ReleaseWriteLock(&client->lock);
@@ -970,9 +985,7 @@
     host->hostFlags &= ~CLIENTDELETED;
 
     if (host->hostFlags & HOSTDELETED) {
-        register struct h_AddrHashChain **ahp, *ath;
 	register struct rx_connection *rxconn;
-	afsUUID *uuidp;
 	struct AddrPort hostAddrPort;
 	int i;
 
@@ -991,44 +1004,22 @@
 
 	/* if alternate addresses do not exist */
 	if (!(host->interface)) {
-	    for (ahp = &hostAddrHashTable[h_HashIndex(host->host)]; (ath = *ahp);
-		 ahp = &ath->next) {
-		assert(ath->hostPtr);
-		if (ath->hostPtr == host) {
-		    *ahp = ath->next;
-		    free(ath);
-		    break;
-		}
-	    }
+	    h_DeleteHostFromAddrHashTable_r(host->host, host->port, host);
 	} else {
-            register struct h_UuidHashChain **uhp, *uth;
-	    /* delete the hash entry for the UUID */
-	    uuidp = &host->interface->uuid;
-	    for (uhp = &hostUuidHashTable[h_UuidHashIndex(uuidp)]; (uth = *uhp);
-		 uhp = &uth->next) {
-		assert(uth->hostPtr);
-		if (uth->hostPtr == host) {
-		    *uhp = uth->next;
-		    free(uth);
-		    break;
-		}
-	    }
-	    /* delete the hash entry for each alternate addresses */
+	    h_DeleteHostFromUuidHashTable_r(host);
+	    h_DeleteHostFromAddrHashTable_r(host->host, host->port, host);
+	    /* delete the hash entry for each valid alternate addresses */
 	    for (i = 0; i < host->interface->numberOfInterfaces; i++) {
 		hostAddrPort = host->interface->interface[i];
-
-                if (!hostAddrPort.valid)
-                    continue;
-
-		for (ahp = &hostAddrHashTable[h_HashIndex(hostAddrPort.addr)]; (ath = *ahp);
-		     ahp = &ath->next) {
-		    assert(ath->hostPtr);
-		    if (ath->hostPtr == host) {
-			*ahp = ath->next;
-			free(ath);
-			break;
-		    }
-		}
+		/*
+		 * if the interface addr/port is the primary, we already
+		 * removed it.  If the addr/port is not valid, its not
+		 * in the hash table.
+		 */
+		if (hostAddrPort.valid &&
+		    (host->host != hostAddrPort.addr ||
+		     host->port != hostAddrPort.port))
+		    h_DeleteHostFromAddrHashTable_r(hostAddrPort.addr, hostAddrPort.port, host);
 	    }
 	    free(host->interface);
 	    host->interface = NULL;
@@ -1184,65 +1175,124 @@
 
 /* inserts a new HashChain structure corresponding to this UUID */
 void
-hashInsertUuid_r(struct afsUUID *uuid, struct host *host)
+h_AddHostToUuidHashTable_r(struct afsUUID *uuid, struct host *host)
 {
     int index;
     struct h_UuidHashChain *chain;
+    char uuid1[128], uuid2[128];
+    char hoststr[16];
 
     /* hash into proper bucket */
     index = h_UuidHashIndex(uuid);
 
     /* don't add the same entry multiple times */
     for (chain = hostUuidHashTable[index]; chain; chain = chain->next) {
+	if (!chain->hostPtr)
+	    continue;
+
 	if (chain->hostPtr->interface && 
-	    afs_uuid_equal(&chain->hostPtr->interface->uuid, uuid))
+	    afs_uuid_equal(&chain->hostPtr->interface->uuid, uuid)) {
+	    if (LogLevel >= 125) {
+		afsUUID_to_string(&chain->hostPtr->interface->uuid, uuid1, 127);
+		afsUUID_to_string(uuid, uuid2, 127);
+		ViceLog(125, ("h_AddHostToUuidHashTable_r: host 0x%lx (uuid %s) exists as %s:%d (uuid %s)\n",
+                             (unsigned long) host, uuid1,
+                             afs_inet_ntoa_r(chain->hostPtr->host, hoststr), 
+                             ntohs(chain->hostPtr->port), uuid2));
+	    }
 	    return;
+	}
     }
 
     /* insert into beginning of list for this bucket */
     chain = (struct h_UuidHashChain *)malloc(sizeof(struct h_UuidHashChain));
     if (!chain) {
-	ViceLog(0, ("Failed malloc in hashInsertUuid_r\n"));
+	ViceLog(0, ("Failed malloc in h_AddHostToUuidHashTable_r\n"));
 	assert(0);
     }
-    assert(chain);
     chain->hostPtr = host;
     chain->next = hostUuidHashTable[index];
     hostUuidHashTable[index] = chain;
+    if (LogLevel < 125)
+	return;
+    afsUUID_to_string(uuid, uuid2, 127);
+    ViceLog(125, 
+            ("h_AddHostToUuidHashTable_r: host 0x%lx (%s:%d) added as uuid %s\n",
+             (unsigned long) host, afs_inet_ntoa_r(chain->hostPtr->host, hoststr),
+             ntohs(chain->hostPtr->port), uuid));
 }
 
+/* deletes a HashChain structure corresponding to this host */
+int
+h_DeleteHostFromUuidHashTable_r(struct host *host)
+{
+    int index;
+    register struct h_UuidHashChain **uhp, *uth;
+    char uuid1[128];
+    char hoststr[16];
+ 
+    if (!host->interface)
+	return 0;
+ 
+    /* hash into proper bucket */
+    index = h_UuidHashIndex(&host->interface->uuid);
+     
+    if (LogLevel >= 125)
+	afsUUID_to_string(&host->interface->uuid, uuid1, 127);
+    for (uhp = &hostUuidHashTable[index]; (uth = *uhp); uhp = &uth->next) {
+	assert(uth->hostPtr);
+	if (uth->hostPtr == host) {
+	    ViceLog(125, 
+                    ("h_DeleteHostFromUuidHashTable_r: host 0x%lx (uuid %s %s:%d)\n",
+                     (unsigned long) host, uuid1, afs_inet_ntoa_r(host->host, hoststr),
+                     ntohs(host->port)));
+	    *uhp = uth->next;
+	    free(uth);
+	    return 1;
+	}
+    }
+    ViceLog(125, 
+            ("h_DeleteHostFromUuidHashTable_r: host 0x%lx (uuid %s %s:%d) not found\n",
+             (unsigned long) host, uuid1, afs_inet_ntoa_r(host->host, hoststr),
+             ntohs(host->port)));
+    return 0;
+}
 
 /* inserts a new HashChain structure corresponding to this address */
 void
-hashInsert_r(afs_uint32 addr, afs_uint16 port, struct host *host)
+h_AddHostToAddrHashTable_r(afs_uint32 addr, afs_uint16 port, struct host *host)
 {
     int index;
     struct h_AddrHashChain *chain;
     int found = 0;
-    char hoststr[16]; 
+    char hoststr[16], hoststr2[16]; 
   
     /* hash into proper bucket */
     index = h_HashIndex(addr);
 
     /* don't add the same entry multiple times */
     for (chain = hostAddrHashTable[index]; chain; chain = chain->next) {
-	if (chain->addr == addr && chain->port == port) {
-	    if (chain->hostPtr == host)
-		found = 1;
-	    else if (!(host->hostFlags & HOSTDELETED))
-		ViceLog(125, ("Addr %s:%d assigned to %x and %x.\n",
-			    afs_inet_ntoa_r(addr, hoststr), ntohs(port),
-			    host, chain));
+	if (chain->hostPtr == host) {
+	    if (chain->addr != addr || chain->port != port) {
+		ViceLog(0, 
+                       ("h_AddHostToAddrHashTable_r: host 0x%lx exists as %s:%d when adding %s:%d\n",
+                        (unsigned long) host, afs_inet_ntoa_r(chain->addr, hoststr),
+                        ntohs(chain->port), afs_inet_ntoa_r(addr, hoststr2), 
+                        ntohs(port)));
+	    } else
+		ViceLog(125, 
+                       ("h_AddHostToAddrHashTable_r: host 0x%lx (%s:%d) already hashed\n",
+                        (unsigned long) host, afs_inet_ntoa_r(chain->addr, hoststr),
+                        ntohs(chain->port)));
+           
+	    return;
 	}
     }
 
-    if (found)
-	return;
-
     /* insert into beginning of list for this bucket */
     chain = (struct h_AddrHashChain *)malloc(sizeof(struct h_AddrHashChain));
     if (!chain) {
-	ViceLog(0, ("Failed malloc in hashInsert_r\n"));
+	ViceLog(0, ("Failed malloc in h_AddHostToAddrHashTable_r\n"));
 	assert(0);
     }
     chain->hostPtr = host;
@@ -1250,13 +1300,14 @@
     chain->addr = addr;
     chain->port = port;
     hostAddrHashTable[index] = chain;
+    ViceLog(125, ("h_AddHostToAddrHashTable_r: host 0x%lx added as %s:%d\n",
+                  (unsigned long) host, afs_inet_ntoa_r(addr, hoststr), ntohs(port)));
 }
 
 /*
- * This is called with host locked and held. At this point, the
- * hostAddrHashTable should not have entries for the alternate
- * interfaces. This function has to insert these entries in the
- * hostAddrHashTable.
+ * This is called with host locked and held. 
+ * It is called to either validate or add an additional interface
+ * address/port on the specified host.  
  *
  * All addresses are in network byte order.
  */
@@ -1279,22 +1330,25 @@
     for (i = 0; i < number; i++) {
 	if (host->interface->interface[i].addr == addr &&
             host->interface->interface[i].port == port) {
-	    ViceLog(125, ("addInterfaceAddr : host %x (%s:%d) addr %s:%d : found, valid: %d\n",
-			  host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port),
-			  afs_inet_ntoa_r(addr, hoststr2), ntohs(port),
-			  host->interface->interface[i].valid));
+	    ViceLog(125, 
+                   ("addInterfaceAddr : found host 0x%lx (%s:%d) adding %s:%d%s\n",
+                    (unsigned long) host, afs_inet_ntoa_r(host->host, hoststr),
+                    ntohs(host->port), afs_inet_ntoa_r(addr, hoststr2), 
+                    ntohs(port), host->interface->interface[i].valid ? "" : 
+                    ", validating"));
 
 	    if (host->interface->interface[i].valid == 0) {
-		hashInsert_r(addr, port, host);
 		host->interface->interface[i].valid = 1;
+		h_AddHostToAddrHashTable_r(addr, port, host);
 	    }
 	    return 0;
         }
     }
 
-    ViceLog(125, ("addInterfaceAddr : host %x (%s:%d) addr %s:%d : not found, adding\n",
-		  host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port),
-		  afs_inet_ntoa_r(addr, hoststr2), ntohs(port)));
+    ViceLog(125, ("addInterfaceAddr : host 0x%lx (%s:%d) adding %s:%d\n",
+                 (unsigned long) host, afs_inet_ntoa_r(host->host, hoststr),
+                 ntohs(host->port), afs_inet_ntoa_r(addr, hoststr2), 
+                 ntohs(port)));
     
     interface = (struct Interface *)
 	malloc(sizeof(struct Interface) + (sizeof(struct AddrPort) * number));
@@ -1306,9 +1360,12 @@
     interface->uuid = host->interface->uuid;
     for (i = 0; i < number; i++)
 	interface->interface[i] = host->interface->interface[i];
+
+    /* Add the new valid interface */
     interface->interface[number].addr = addr;
     interface->interface[number].port = port;
     interface->interface[number].valid = 1;
+    h_AddHostToAddrHashTable_r(addr, port, host);
     free(host->interface);
     host->interface = interface;
 
@@ -1317,10 +1374,7 @@
 
 
 /*
- * This is called with host locked and held. At this point, the
- * hostAddrHashTable should not be having entries for the alternate
- * interfaces. This function has to insert these entries in the
- * hostAddrHashTable.
+ * This is called with host locked and held.
  *
  * All addresses are in network byte order.
  */
@@ -1329,16 +1383,16 @@
 {
     int i;
     int number;
-    int found;
     struct Interface *interface;
     char hoststr[16], hoststr2[16];
 
     assert(host);
     assert(host->interface);
 
-    ViceLog(125, ("removeInterfaceAddr : host %x (%s:%d) addr %s:%d\n", 
-		   host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port), 
-		   afs_inet_ntoa_r(addr, hoststr2), ntohs(port)));
+    ViceLog(125, ("removeInterfaceAddr : host 0x%lx (%s:%d) addr %s:%d\n",
+                 (unsigned long) host, afs_inet_ntoa_r(host->host, hoststr),
+                 ntohs(host->port), afs_inet_ntoa_r(addr, hoststr2), 
+                 ntohs(port)));
 
     /*
      * Make sure this address is on the list of known addresses
@@ -1346,26 +1400,62 @@
      */
     interface = host->interface;
     number = host->interface->numberOfInterfaces;
-    for (i = 0, found = 0; i < number && !found; i++) {
-	if (interface->interface[i].addr == addr &&
-	    interface->interface[i].port == port) {
-	    found = 1;
-            interface->interface[i].valid = 0;
-	}
-    }
-    if (found) {
-	number--;
-	for (; i < number; i++) {
-	    interface->interface[i] = interface->interface[i+1];
+    for (i = 0; i < number; i++) {
+        if (interface->interface[i].addr == addr &&
+            interface->interface[i].port == port) {
+	    if (interface->interface[i].valid)
+		h_DeleteHostFromAddrHashTable_r(addr, port, host);
+	    number--;
+	    for (; i < number; i++) {
+		interface->interface[i] = interface->interface[i+1];
+	    }
+	    interface->numberOfInterfaces = number;
+	    return 0;
 	}
-	interface->numberOfInterfaces = number;
-    }
+    }  
+    /* not found */
+    return 0;
+}
+
+/*
+ * This is called with host locked and held.
+ *
+ * All addresses are in network byte order.
+ */
+int
+invalidateInterfaceAddr_r(struct host *host, afs_uint32 addr, afs_uint16 port)
+{
+    int i;
+    int number;
+    struct Interface *interface;
+    char hoststr[16], hoststr2[16];
+
+    assert(host);
+    assert(host->interface);
+    
+    ViceLog(125, ("invalidateInterfaceAddr : host 0x%lx (%s:%d) addr %s:%d\n",
+                 (unsigned long) host, afs_inet_ntoa_r(host->host, hoststr),
+                 ntohs(host->port), afs_inet_ntoa_r(addr, hoststr2), 
+                 ntohs(port)));
 
     /*
-     * Remove the hash table entry for this address
+     * Make sure this address is on the list of known addresses
+     * for this host.
      */
-    hashDelete_r(addr, port, host);
-
+    interface = host->interface;
+    number = host->interface->numberOfInterfaces;
+    for (i = 0; i < number; i++) {
+	if (interface->interface[i].addr == addr &&
+            interface->interface[i].port == port) {
+	    if (interface->interface[i].valid) {
+		h_DeleteHostFromAddrHashTable_r(addr, port, host);
+		interface->interface[i].valid = 0;
+	    }
+	    return 0;
+	}
+    }
+    
+    /* not found */
     return 0;
 }
 
@@ -1383,62 +1473,53 @@
 {
     int i;
     char hoststr[16], hoststr2[16];
+    struct rx_connection *rxconn;
 
-    if (!host->interface) {
+    if (!host->interface || host->interface->numberOfInterfaces == 1) {
         if (host->host == addr && host->port == port) {
             ViceLog(25,
-                    ("Removing only address for host %x (%s:%d), deleting host.\n",
-                     host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
+                    ("Removing only address for host 0x%lx (%s:%d), deleting host.\n",
+                     (unsigned long) host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
             host->hostFlags |= HOSTDELETED;
+            /* 
+             * Do not remove the primary addr/port from the hash table.
+             * It will be ignored due to the HOSTDELETED flag and will
+             * be removed when h_TossStuff_r() cleans up the HOSTDELETED
+             * host.  Removing it here will only result in a search for 
+             * the host/addr/port in the hash chain which will fail.
+             */
+	} else {
+            ViceLog(0,
+                    ("Removing address that does not belong to host 0x%lx (%s:%d).\n",
+                     (unsigned long) host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
         }
     } else {
-        removeInterfaceAddr_r(host, host->host, host->port);
-        if (host->interface->numberOfInterfaces == 0) {
-            ViceLog(25,
-                     ("Removed only address for host %x (%s:%d), no alternate interfaces, deleting host.\n",
-                       host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
-            host->hostFlags |= HOSTDELETED;
-        } else {
+	if (host->host == addr && host->port == port)  {
+	    removeInterfaceAddr_r(host, addr, port);
 
             for (i=0; i < host->interface->numberOfInterfaces; i++) {
                 if (host->interface->interface[i].valid) {
                     ViceLog(25,
-                             ("Removed address for host %x (%s:%d), new primary interface %s:%d.\n",
-                               host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port),
+                             ("Removed address for host 0x%lx (%s:%d), new primary interface %s:%d.\n",
+                               (unsigned long) host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port),
                                afs_inet_ntoa_r(host->interface->interface[i].addr, hoststr2), 
                                ntohs(host->interface->interface[i].port)));
                     host->host = host->interface->interface[i].addr;
                     host->port = host->interface->interface[i].port;
-                    hashInsert_r(host->host, host->port, host);
+                    h_AddHostToAddrHashTable_r(host->host, host->port, host);
                     break;
                 }
             }
 
             if (i == host->interface->numberOfInterfaces) {
                 ViceLog(25,
-                         ("Removed only address for host %x (%s:%d), no valid alternate interfaces, deleting host.\n",
-                           host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
+                         ("Removed only address for host 0x%lx (%s:%d), no valid alternate interfaces, deleting host.\n",
+                          (unsigned long) host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
                 host->hostFlags |= HOSTDELETED;
+		/* addr/port was removed from the hash table */
+		host->host = 0;
+		host->port = 0;
             } else {
-                struct rx_connection *rxconn;
-
-                rxconn = host->callback_rxcon;
-                host->callback_rxcon = NULL;
-
-                if (rxconn) {
-                    struct client *client;
-                    /*
-                    * If rx_DestroyConnection calls h_FreeConnection we will
-                    * deadlock on the host_glock_mutex. Work around the problem
-                    * by unhooking the client from the connection before
-                    * destroying the connection.
-                    */
-                    client = rx_GetSpecific(rxconn, rxcon_client_key);
-                    rx_SetSpecific(rxconn, rxcon_client_key, (void *)0);
-                    rx_DestroyConnection(rxconn);
-		    rxconn = NULL;
-                }
-
                 if (!sc)
                     sc = rxnull_NewClientSecurityObject();
                 host->callback_rxcon =
@@ -1446,6 +1527,9 @@
                 rx_SetConnDeadTime(host->callback_rxcon, 50);
                 rx_SetConnHardDeadTime(host->callback_rxcon, AFS_HARDDEADTIME);
             }
+	} else {
+	    /* not the primary addr/port, just invalidate it */
+	    invalidateInterfaceAddr_r(host, addr, port);
         }
     }
 
@@ -1527,8 +1611,8 @@
              * waited for the lock. */
 	    h_Unlock_r(host);
 	    ViceLog(125,
-		    ("Host %s:%d starting h_Lookup again\n",
-		     afs_inet_ntoa_r(host->host, hoststr),
+		    ("Host 0x%lx (%s:%d) starting h_Lookup again\n",
+		     (unsigned long) host, afs_inet_ntoa_r(host->host, hoststr),
 		     ntohs(host->port)));
 	    if (!*heldp)
 		h_Release_r(host);
@@ -1594,8 +1678,8 @@
 		 * that we maintain some extra callback state information */
 		if (host->interface) {
 		    ViceLog(0,
-			    ("Host %x (%s:%d) used to support WhoAreYou, deleting.\n",
-			     host, 
+			    ("Host 0x%lx (%s:%d) used to support WhoAreYou, deleting.\n",
+			     (unsigned long) host,
 			     afs_inet_ntoa_r(host->host, hoststr),
 			     ntohs(host->port)));
 		    host->hostFlags |= HOSTDELETED;
@@ -1646,8 +1730,8 @@
                     removeAddress_r(host, haddr, hport);
 		} else {
 		    ViceLog(25,
-			    ("Uuid doesn't match host %x (%s:%d).\n",
-			     host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
+			    ("Uuid doesn't match host 0x%lx (%s:%d).\n",
+			     (unsigned long) host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
 		    
 		    removeAddress_r(host, host->host, host->port);
 		}
@@ -1684,8 +1768,8 @@
                      * callback connection, and destroy the old one.
                      */
                     struct rx_connection *rxconn;
-                    ViceLog(0,("CB: ProbeUuid for host %x (%s:%d) failed %d\n",
-			       host, 
+                    ViceLog(0,("CB: ProbeUuid for host 0x%lx (%s:%d) failed %d\n",
+			       (unsigned long) host,
 			       afs_inet_ntoa_r(host->host, hoststr),
 			       ntohs(host->port),code2));
 		    /*
@@ -1736,8 +1820,8 @@
 		goto gethost_out;
 	    } else {
 		ViceLog(0,
-			("CB: WhoAreYou failed for host %x (%s:%d), error %d\n",
-			 host, afs_inet_ntoa_r(host->host, hoststr),
+			("CB: WhoAreYou failed for host 0x%lx (%s:%d), error %d\n",
+			 (unsigned long) host, afs_inet_ntoa_r(host->host, hoststr),
 			 ntohs(host->port), code));
 		host->hostFlags |= VENUSDOWN;
 	    }
@@ -1754,14 +1838,14 @@
 	if (!(host->hostFlags & ALTADDR)) {
 	    /* another thread is doing the initialisation */
 	    ViceLog(125,
-		    ("Host %s:%d waiting for host-init to complete\n",
-		     afs_inet_ntoa_r(host->host, hoststr),
+		    ("Host 0x%lx (%s:%d) waiting for host-init to complete\n",
+		     (unsigned long) host, afs_inet_ntoa_r(host->host, hoststr),
 		     ntohs(host->port)));
 	    h_Lock_r(host);
 	    h_Unlock_r(host);
 	    ViceLog(125,
-		    ("Host %s:%d starting h_Lookup again\n",
-		     afs_inet_ntoa_r(host->host, hoststr),
+		    ("Host 0x%lx (%s:%d) starting h_Lookup again\n",
+		     (unsigned long) host, afs_inet_ntoa_r(host->host, hoststr),
 		     ntohs(host->port)));
 	    if (!*heldp)
 		h_Release_r(host);
@@ -1782,8 +1866,8 @@
 	    if (host->interface)
 		afsUUID_to_string(&host->interface->uuid, uuid2, 127);
 	    ViceLog(0,
-		    ("CB: new identity for host %s:%d, deleting(%x %x %s %s)\n",
-		     afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port),
+		    ("CB: new identity for host 0x%lx (%s:%d), deleting(%x %x %s %s)\n",
+		     (unsigned long) host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port),
 		     identP->valid, host->interface,
 		     identP->valid ? uuid1 : "",
 		     host->interface ? uuid2 : ""));
@@ -1829,8 +1913,8 @@
 		if (!pident)
 		    rx_SetSpecific(tcon, rxcon_ident_key, identP);
 		ViceLog(25,
-			("Host %s:%d does not support WhoAreYou.\n",
-			 afs_inet_ntoa_r(host->host, hoststr),
+			("Host 0x%lx (%s:%d) does not support WhoAreYou.\n",
+			 (unsigned long) host, afs_inet_ntoa_r(host->host, hoststr),
 			 ntohs(host->port)));
 		code = 0;
 	    } else if (code == 0) {
@@ -1850,8 +1934,8 @@
 		if (!pident)
 		    rx_SetSpecific(tcon, rxcon_ident_key, identP);
 		ViceLog(25,
-			("WhoAreYou success on %s:%d\n",
-			 afs_inet_ntoa_r(host->host, hoststr),
+			("WhoAreYou success on 0x%lx (%s:%d)\n",
+			 (unsigned long) host, afs_inet_ntoa_r(host->host, hoststr),
 			 ntohs(host->port)));
 	    }
 	    if (code == 0 && !identP->valid) {
@@ -1906,8 +1990,8 @@
 			     * MultiProbeAlternateAddress_r() will remove the
 			     * alternate interfaces that do not have the same
 			     * Uuid. */
-			    ViceLog(0,("CB: ProbeUuid for %s:%d failed %d\n",
-					 afs_inet_ntoa_r(oldHost->host, hoststr),
+			    ViceLog(0,("CB: ProbeUuid for 0x%lx (%s:%d) failed %d\n",
+                                        (unsigned long) oldHost, afs_inet_ntoa_r(oldHost->host, hoststr),
 					 ntohs(oldHost->port),code2));
 			    MultiProbeAlternateAddress_r(oldHost);
                             probefail = 1;
@@ -1927,8 +2011,8 @@
 			struct rx_connection *rxconn;
 
 			ViceLog(25,
-				("CB: Host %x (%s:%d) has new addr %s:%d\n",
-				  oldHost, 
+				("CB: Host 0x%lx (%s:%d) has new addr %s:%d\n",
+                                  (unsigned long) oldHost,
                                   afs_inet_ntoa_r(oldHost->host, hoststr2),
 				  ntohs(oldHost->port),
                                   afs_inet_ntoa_r(haddr, hoststr),
@@ -1947,23 +2031,24 @@
 			     */
 			    removeInterfaceAddr_r(oldHost, oldHost->host, oldHost->port);
 			} else {
-			    int i, found;
+			    int i;
 			    struct Interface *interface = oldHost->interface;
 			    int number = oldHost->interface->numberOfInterfaces;
-			    for (i = 0, found = 0; i < number; i++) {
+			    for (i = 0; i < number; i++) {
 				if (interface->interface[i].addr == haddr &&
 				    interface->interface[i].port != hport) {
-				    found = 1;
+				    /* 
+				     * We have just been contacted by a client
+				     * that has been seen from behind a NAT 
+				     * and at least one other address.
+				     */
+				    removeInterfaceAddr_r(oldHost, haddr, 
+					interface->interface[i].port);
 				    break;
 				}
 			    }
-			    if (found) {
-				/* We have just been contacted by a client that has been
-				 * seen from behind a NAT and at least one other address.
-				 */
-				removeInterfaceAddr_r(oldHost, haddr, interface->interface[i].port);
-			    }
 			}
+			h_AddHostToAddrHashTable_r(haddr, hport, oldHost);
 			oldHost->host = haddr;
 			oldHost->port = hport;
 			rxconn = oldHost->callback_rxcon;
@@ -1982,7 +2067,7 @@
 		    /* the new host is held and locked */
 		} else {
 		    /* This really is a new host */
-		    hashInsertUuid_r(&identP->uuid, host);
+		    h_AddHostToUuidHashTable_r(&identP->uuid, host);
 		    cb_conn = host->callback_rxcon;
 		    rx_GetConnection(cb_conn);		
 		    H_UNLOCK;
@@ -1994,8 +2079,8 @@
 		    H_LOCK;
 		    if (code == 0) {
 			ViceLog(25,
-				("InitCallBackState3 success on %s:%d\n",
-				 afs_inet_ntoa_r(host->host, hoststr),
+				("InitCallBackState3 success on 0x%lx (%s:%d)\n",
+				 (unsigned long) host, afs_inet_ntoa_r(host->host, hoststr),
 				 ntohs(host->port)));
 			assert(interfValid == 1);
 			initInterfaceAddr_r(host, &interf);
@@ -2004,13 +2089,13 @@
 	    }
 	    if (code) {
 		ViceLog(0,
-			("CB: RCallBackConnectBack failed for host %x (%s:%d)\n",
-			 host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
+			("CB: RCallBackConnectBack failed for host 0x%lx (%s:%d)\n",
+			 (unsigned long) host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
 		host->hostFlags |= VENUSDOWN;
 	    } else {
 		ViceLog(125,
-			("CB: RCallBackConnectBack succeeded for host %x (%s:%d)\n",
-			 host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
+			("CB: RCallBackConnectBack succeeded for host 0x%lx (%s:%d)\n",
+			 (unsigned long) host, afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
 		host->hostFlags |= RESETDONE;
 	    }
 	}
@@ -2358,8 +2443,8 @@
 	    if (code) {
 		char hoststr[16];
 		ViceLog(0,
-			("pr_GetCPS failed(%d) for user %d, host %s:%d\n",
-			 code, viceid, afs_inet_ntoa_r(client->host->host,
+			("pr_GetCPS failed(%d) for user %d, host 0x%lx (%s:%d)\n",
+			 code, viceid, (unsigned long) client->host, afs_inet_ntoa_r(client->host->host,
 						       hoststr),
 			 ntohs(client->host->port)));
 
@@ -3012,7 +3097,7 @@
 		     * back state, because break delayed callbacks (called when a
 		     * message is received from the workstation) will always send a 
 		     * break all call backs to the workstation if there is no
-		     *callback.
+		     * callback.
 		     */
 		}
 	    } else {
@@ -3105,7 +3190,7 @@
 		     * back state, because break delayed callbacks (called when a
 		     * message is received from the workstation) will always send a 
 		     * break all call backs to the workstation if there is no
-		     *callback.
+		     * callback.
 		     */
 		}
 	    } else {
@@ -3178,9 +3263,8 @@
 
 /*
  * This is called with host locked and held. At this point, the
- * hostAddrHashTable should not have any entries for the alternate
- * interfaces. This function has to insert these entries in the
- * hostAddrHashTable.
+ * hostAddrHashTable has an entry for the primary addr/port inserted
+ * by h_Alloc_r().  No other interfaces should be considered valid.
  *
  * The addresses in the interfaceAddr list are in host byte order.
  */
@@ -3298,7 +3382,8 @@
 	 * are coming from fully connected hosts (no NAT/PATs)
 	 */
 	interface->interface[i].port = port7001;
-        interface->interface[i].valid = 1;      /* valid until a conflict is found */
+	interface->interface[i].valid = 
+	    (interf->addr_in[i] == myAddr && port7001 == myPort) ? 1 : 0;
     }
 
     interface->uuid = interf->uuid;
@@ -3306,13 +3391,15 @@
     assert(!host->interface);
     host->interface = interface;
 
-    afsUUID_to_string(&interface->uuid, uuidstr, 127);
-
-    ViceLog(125, ("--- uuid %s\n", uuidstr));
-    for (i = 0; i < host->interface->numberOfInterfaces; i++) {
-	ViceLog(125, ("--- alt address %s:%d\n", 
-		       afs_inet_ntoa_r(host->interface->interface[i].addr, hoststr),
-		       ntohs(host->interface->interface[i].port)));
+    if (LogLevel >= 125) {
+	afsUUID_to_string(&interface->uuid, uuidstr, 127);
+       
+	ViceLog(125, ("--- uuid %s\n", uuidstr));
+	for (i = 0; i < host->interface->numberOfInterfaces; i++) {
+	    ViceLog(125, ("--- alt address %s:%d\n", 
+		afs_inet_ntoa_r(host->interface->interface[i].addr, hoststr),
+		ntohs(host->interface->interface[i].port)));
+	}
     }
 
     return 0;
@@ -3321,24 +3408,32 @@
 /* deleted a HashChain structure for this address and host */
 /* returns 1 on success */
 int
-hashDelete_r(afs_uint32 addr, afs_uint16 port, struct host *
-				host)
+h_DeleteHostFromAddrHashTable_r(afs_uint32 addr, afs_uint16 port, 
+                               struct host *host)
 {
-    int flag = 0;
+    char hoststr[16];
     register struct h_AddrHashChain **hp, *th;
 
-    for (hp = &hostAddrHashTable[h_HashIndex(addr)]; (th = *hp);) {
+    if (addr == 0 && port == 0)
+	return 1;
+
+    for (hp = &hostAddrHashTable[h_HashIndex(addr)]; (th = *hp); 
+	hp = &th->next) {
 	assert(th->hostPtr);
 	if (th->hostPtr == host && th->addr == addr && th->port == port) {
+	    ViceLog(125, ("h_DeleteHostFromAddrHashTable_r: host 0x%lx (%s:%d)\n",
+                         (unsigned long) host, afs_inet_ntoa_r(host->host, hoststr),
+                         ntohs(host->port)));
 	    *hp = th->next;
 	    free(th);
-	    flag = 1;
-	    break;
-	} else {
-	    hp = &th->next;
-	}
+	    return 1;
+        }
     }
-    return flag;
+    ViceLog(125, 
+           ("h_DeleteHostFromAddrHashTable_r: host 0x%lx (%s:%d) not found\n",
+            (unsigned long) host, afs_inet_ntoa_r(host->host, hoststr),
+            ntohs(host->port)));
+    return 0;
 }
 
 
@@ -3355,9 +3450,9 @@
     if (host->interface) {
 	/* check alternate addresses */
 	number = host->interface->numberOfInterfaces;
-        if (number == 0)
+        if (number == 0) {
             ViceLog(level, ("no-addresses "));
-        else {
+        } else {
             for (i = 0; i < number; i++)
                 ViceLog(level, ("%s:%d ", afs_inet_ntoa_r(host->interface->interface[i].addr, hoststr),
                                 ntohs(host->interface->interface[i].port)));