avoid-client-connection-mismatches-20030213
[openafs.git] / src / viced / host.c
index 98de75d..209a006 100644 (file)
@@ -22,6 +22,15 @@ RCSID("$Header$");
 #include <netdb.h>
 #include <netinet/in.h>
 #endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+
 #include <afs/stds.h>
 #include <rx/xdr.h>
 #include <afs/assert.h>
@@ -45,6 +54,7 @@ RCSID("$Header$");
 #include <rx/rx.h>
 #include <afs/cellconfig.h>
 #include <stdlib.h>
+#include "viced_prototypes.h"
 #include "viced.h"
 #include "host.h"
 
@@ -133,7 +143,6 @@ static void GetCEBlock()
 
 /* get the next available CE */
 static struct client *GetCE()
-
 {
     register struct client *entry;
 
@@ -154,9 +163,7 @@ static struct client *GetCE()
 
 
 /* return an entry to the free list */
-static void FreeCE(entry)
-    register struct client *entry;
-
+static void FreeCE(register struct client *entry)
 {
     entry->next = CEFree;
     CEFree = entry;
@@ -190,7 +197,6 @@ struct HTBlock              /* block of HTSPERBLOCK file entries */
 
 /* get a new block of HTs and chain it on HTFree */
 static void GetHTBlock()
-
 {
     register struct HTBlock *block;
     register int i;
@@ -221,7 +227,6 @@ static void GetHTBlock()
 
 /* get the next available HT */
 static struct host *GetHT()
-
 {
     register struct host *entry;
 
@@ -238,9 +243,7 @@ static struct host *GetHT()
 
 
 /* return an entry to the free list */
-static void FreeHT(entry)
-    register struct host *entry; 
-
+static void FreeHT(register struct host *entry)
 {
     entry->next = HTFree;
     HTFree = entry;
@@ -251,8 +254,7 @@ static void FreeHT(entry)
 
 static short consolePort = 0;
 
-int h_Release(host)
-    register struct host *host;
+int h_Release(register struct host *host)
 {
     H_LOCK
     h_Release_r(host);
@@ -266,8 +268,7 @@ int h_Release(host)
  * If either the HOSTDELETED or CLIENTDELETED flags are set
  * then toss the host
  */
-int h_Release_r(host)
-    register struct host *host;
+int h_Release_r(register struct host *host)
 {      
     
     if (!((host)->holds[h_holdSlot()] & ~h_holdbit()) ) {
@@ -287,18 +288,7 @@ int h_Release_r(host)
     return 0;
 }
 
-int h_Held(host)
-    register struct host *host;
-{
-    int retVal;
-    H_LOCK
-    retVal = h_Held_r(host);
-    H_UNLOCK
-    return retVal;
-}
-
-int h_OtherHolds_r(host)
-    register struct host *host;
+int h_OtherHolds_r(register struct host *host)
 {
     register int i, bit, slot;
     bit = h_holdbit();
@@ -311,18 +301,7 @@ int h_OtherHolds_r(host)
     return 0;
 }
 
-int h_OtherHolds(host)
-    register struct host *host;
-{
-    int retVal;
-    H_LOCK
-    retVal = h_OtherHolds_r(host);
-    H_UNLOCK
-    return retVal;
-}
-
-int h_Lock_r(host)
-    register struct host *host;
+int h_Lock_r(register struct host *host)
 {
     H_UNLOCK
     h_Lock(host);
@@ -336,8 +315,7 @@ int h_Lock_r(host)
   * else returns locks and returns 0
   */
 
-int h_NBLock_r(host)
-    register struct host *host;
+int h_NBLock_r(register struct host *host)
 {
     struct Lock *hostLock = &host->lock;
     int locked = 0;
@@ -386,10 +364,7 @@ int h_NBLock_r(host)
  *     As advertised.
  *------------------------------------------------------------------------*/
 
-static char h_AddrInSameNetwork(a_targetAddr, a_candAddr)
-    afs_uint32 a_targetAddr;
-    afs_uint32 a_candAddr;
-
+static char h_AddrInSameNetwork(afs_uint32 a_targetAddr, afs_uint32 a_candAddr)
 { /*h_AddrInSameNetwork*/
 
     afs_uint32 targetNet;
@@ -443,9 +418,8 @@ static char h_AddrInSameNetwork(a_targetAddr, a_candAddr)
 
 
 
-h_gethostcps_r(host,now)
-    register struct host *host;
-    register afs_int32   now;
+void
+h_gethostcps_r(register struct host *host, register afs_int32 now)
 {
     register int code;
     int  slept=0, held;
@@ -456,10 +430,10 @@ h_gethostcps_r(host,now)
                h_Hold_r(host);
 
        /* wait if somebody else is already doing the getCPS call */
-    while ( host->hostFlags & HPCS_INPROGRESS ) 
+    while ( host->hostFlags & HCPS_INPROGRESS ) 
     {
        slept = 1;              /* I did sleep */
-       host->hostFlags |= HPCS_WAITING; /* I am sleeping now */
+       host->hostFlags |= HCPS_WAITING; /* I am sleeping now */
 #ifdef AFS_PTHREAD_ENV
        pthread_cond_wait(&host->cond, &host_glock_mutex);
 #else /* AFS_PTHREAD_ENV */
@@ -469,10 +443,10 @@ h_gethostcps_r(host,now)
     }
 
 
-    host->hostFlags |= HPCS_INPROGRESS;        /* mark as CPSCall in progress */
+    host->hostFlags |= HCPS_INPROGRESS;        /* mark as CPSCall in progress */
     if (host->hcps.prlist_val)
        free(host->hcps.prlist_val);    /* this is for hostaclRefresh */
-    host->hcps.prlist_val = (afs_int32 *)0;
+    host->hcps.prlist_val = NULL;
     host->hcps.prlist_len = 0;
     slept? (host->cpsCall = FT_ApproxTime()): (host->cpsCall = now );
 
@@ -507,16 +481,16 @@ h_gethostcps_r(host,now)
        }
        if (host->hcps.prlist_val)
            free(host->hcps.prlist_val);
-       host->hcps.prlist_val = (afs_int32 *)0;
+       host->hcps.prlist_val = NULL;
        host->hcps.prlist_len = 0;      /* Make sure it's zero */
     } else
        host->hcpsfailed = 0;
 
-    host->hostFlags &=  ~HPCS_INPROGRESS;
+    host->hostFlags &=  ~HCPS_INPROGRESS;
                                        /* signal all who are waiting */
-    if ( host->hostFlags & HPCS_WAITING) /* somebody is waiting */
+    if ( host->hostFlags & HCPS_WAITING) /* somebody is waiting */
     {
-        host->hostFlags &= ~HPCS_WAITING;
+        host->hostFlags &= ~HCPS_WAITING;
 #ifdef AFS_PTHREAD_ENV
        assert(pthread_cond_broadcast(&host->cond) == 0);
 #else /* AFS_PTHREAD_ENV */
@@ -551,23 +525,11 @@ return;
 
 /*
  * Allocate a host.  It will be identified by the peer (ip,port) info in the
- * rx connection provided.  The host is returned un-held and un-locked
+ * rx connection provided.  The host is returned held and locked
  */
 #define        DEF_ROPCONS 2115
 
-struct host *h_Alloc(r_con)
-    register struct rx_connection *r_con;
-{
-    struct host *retVal;
-    H_LOCK
-    retVal = h_Alloc_r(r_con);
-    H_UNLOCK
-    return retVal;
-}
-
-struct host *h_Alloc_r(r_con)
-    register struct rx_connection *r_con;
-
+struct host *h_Alloc_r(register struct rx_connection *r_con)
 {
     register int code;
     struct servent *serverentry;
@@ -583,7 +545,10 @@ struct host *h_Alloc_r(r_con)
     host = GetHT();
 
     h_hashChain = (struct h_hashChain*) malloc(sizeof(struct h_hashChain));
-    assert(h_hashChain);
+    if (!h_hashChain) {
+        ViceLog(0, ("Failed malloc in h_Alloc_r\n"));
+        assert(0);
+    }
     h_hashChain->hostPtr = host;
     h_hashChain->addr = rxr_HostOf(r_con);
     h_hashChain->next = hostHashTable[index];
@@ -607,7 +572,7 @@ struct host *h_Alloc_r(r_con)
        makes a request that causes a break call back.  It shouldn't. */
     {
        if (!sc)
-           sc = (struct rx_securityClass *) rxnull_NewClientSecurityObject();
+           sc = rxnull_NewClientSecurityObject();
        host->callback_rxcon = rx_NewConnection (host->host, host->port,
                                                 1, sc, 0);
        rx_SetConnDeadTime(host->callback_rxcon, 50);
@@ -615,13 +580,17 @@ struct host *h_Alloc_r(r_con)
     }
     now = host->LastCall = host->cpsCall = host->ActiveCall = FT_ApproxTime();
     host->hostFlags = 0;
-    host->hcps.prlist_val = (afs_int32 *)0;
+    host->hcps.prlist_val = NULL;
     host->hcps.prlist_len = 0;
-    host->hcps.prlist_val = (afs_int32 *)0;
+    host->hcps.prlist_val = NULL;
     host->interface = 0;
-    /*host->hcpsfailed = 0;    /* save cycles */
-    /* h_gethostcps(host);      do this under host lock */
+#ifdef undef
+    host->hcpsfailed = 0;      /* save cycles */
+    h_gethostcps(host);      /* do this under host lock */
+#endif
     host->FirstClient = 0;      
+    h_Hold_r(host);
+    h_Lock_r(host);
     h_InsertList_r(host);      /* update global host List */
 #if FS_STATS_DETAILED
     /*
@@ -634,25 +603,14 @@ struct host *h_Alloc_r(r_con)
 #endif /* FS_STATS_DETAILED */
     return host;
 
-} /*h_Alloc*/
+} /*h_Alloc_r*/
 
 
 /* Lookup a host given an IP address and UDP port number. */
-struct host *h_Lookup(hostaddr, hport, heldp)
-    afs_uint32 hostaddr, hport;     /* network byte order */
-    int *heldp;
-{
-    struct host *retVal;
-    H_LOCK
-    retVal = h_Lookup_r(hostaddr, hport, heldp);
-    H_UNLOCK
-    return retVal;
-}
-
+/* hostaddr and hport are in network order */
 /* Note: host should be released by caller if 0 == *heldp and non-null */
-struct host *h_Lookup_r(hostaddr, hport, heldp)
-    afs_uint32 hostaddr, hport;     /* network byte order */
-    int *heldp;
+/* hostaddr and hport are in network order */
+struct host *h_Lookup_r(afs_uint32 hostaddr, afs_uint32 hport, int *heldp)
 {
     register afs_int32 now;
     register struct host *host=0;
@@ -696,8 +654,7 @@ restart:
 } /*h_Lookup*/
 
 /* Lookup a host given its UUID. */
-struct host *h_LookupUuid_r(uuidp)
-    afsUUID *uuidp;
+struct host *h_LookupUuid_r(afsUUID *uuidp)
 {
     register struct host *host=0;
     register struct h_hashChain* chain;
@@ -718,31 +675,18 @@ struct host *h_LookupUuid_r(uuidp)
 
 
 /*
- * h_Hold: Establish a hold by the current LWP on this host--the host
+ * h_Hold_r: Establish a hold by the current LWP on this host--the host
  * or its clients will not be physically deleted until all holds have
  * been released.
- *
  * NOTE: h_Hold_r is a macro defined in host.h.
  */
 
-int h_Hold(host)
-    register struct host *host;
-{
-    H_LOCK
-    h_Hold_r(host);
-    H_UNLOCK
-    return 0;
-}
-
-
-/* h_TossStuff:  Toss anything in the host structure (the host or
- * clients marked for deletion.  Called from r_Release ONLY.
+/* h_TossStuff_r:  Toss anything in the host structure (the host or
+ * clients marked for deletion.  Called from h_Release_r ONLY.
  * To be called, there must be no holds, and either host->deleted
  * or host->clientDeleted must be set.
  */
-h_TossStuff_r(host)
-    register struct host *host;
-
+int h_TossStuff_r(register struct host *host)
 {
     register struct client **cp, *client;
     int                i;
@@ -752,12 +696,22 @@ h_TossStuff_r(host)
     if  (i!=h_maxSlots)
        return;
 
+    /* if somebody still has this host locked */
+    if (h_NBLock_r(host) != 0) {
+       char hoststr[16];
+       ViceLog(0, ("Warning:  h_TossStuff_r failed; Host %s:%d was locked.\n",
+                   afs_inet_ntoa_r(host->host, hoststr), host->port)); 
+       return;
+    } else {
+       h_Unlock_r(host);
+    }
+
     /* ASSUMPTION: r_FreeConnection() does not yield */
-    for (cp = &host->FirstClient; client = *cp; ) {
+    for (cp = &host->FirstClient; (client = *cp); ) {
        if ((host->hostFlags & HOSTDELETED) || client->deleted) {
            if ((client->ViceId != ANONYMOUSID) && client->CPS.prlist_val) {
                free(client->CPS.prlist_val);
-                client->CPS.prlist_val = (afs_int32 *)0;
+                client->CPS.prlist_val = NULL;
            }
            if (client->tcon) {
                rx_SetSpecific(client->tcon, rxcon_client_key, (void *)0);
@@ -779,7 +733,7 @@ h_TossStuff_r(host)
        int i;
 
        if (host->Console & 1) Console--;
-       if (rxconn = host->callback_rxcon) {
+       if ((rxconn = host->callback_rxcon)) {
            host->callback_rxcon = (struct rx_connection *)0;
            /*
             * If rx_DestroyConnection calls h_FreeConnection we will
@@ -795,16 +749,16 @@ h_TossStuff_r(host)
        }
        if (host->hcps.prlist_val)
            free(host->hcps.prlist_val);
-       host->hcps.prlist_val = (afs_int32 *)0;
+       host->hcps.prlist_val = NULL;
        host->hcps.prlist_len = 0;
-       DeleteAllCallBacks_r(host);
+       DeleteAllCallBacks_r(host, 1);
        host->hostFlags &= ~RESETDONE;  /* just to be safe */
 
        /* if alternate addresses do not exist */
        if ( !(host->interface) )
        {
                for (hp = &hostHashTable[h_HashIndex(host->host)];
-                       th = *hp; hp = &th->next) 
+                       (th = *hp); hp = &th->next) 
                {
                        assert(th->hostPtr);
                        if (th->hostPtr == host) 
@@ -821,7 +775,7 @@ h_TossStuff_r(host)
            /* delete all hash entries for the UUID */
            uuidp = &host->interface->uuid;
            for (hp = &hostUuidHashTable[h_UuidHashIndex(uuidp)];
-                th = *hp; hp = &th->next) {
+                (th = *hp); hp = &th->next) {
                assert(th->hostPtr);
                if (th->hostPtr == host)
                {
@@ -836,7 +790,7 @@ h_TossStuff_r(host)
            {
                hostAddr = host->interface->addr[i];
                for (hp = &hostHashTable[h_HashIndex(hostAddr)];
-                       th = *hp; hp = &th->next) 
+                       (th = *hp); hp = &th->next) 
                {
                        assert(th->hostPtr);
                        if (th->hostPtr == host) 
@@ -857,9 +811,7 @@ h_TossStuff_r(host)
 
 
 /* Called by rx when a server connection disappears */
-h_FreeConnection(tcon)
-    struct rx_connection *tcon;
-
+int h_FreeConnection(struct rx_connection *tcon)
 {
     register struct client *client;
 
@@ -880,10 +832,7 @@ h_FreeConnection(tcon)
  * to (*proc) as the param held.  The proc should return 0 if the host should be
  * released, 1 if it should be held after enumeration.
  */
-h_Enumerate(proc, param)
-    int (*proc)();
-    char *param;
-
+void h_Enumerate(int (*proc)(), char *param)
 {
     register struct host *host, **list;
     register int *held;
@@ -895,9 +844,15 @@ h_Enumerate(proc, param)
        return;
     }
     list = (struct host **)malloc(hostCount * sizeof(struct host *));
-    assert(list != NULL);
+    if (!list) {
+        ViceLog(0, ("Failed malloc in h_Enumerate\n"));
+       assert(0);
+    }
     held = (int *)malloc(hostCount * sizeof(int));
-    assert(held != NULL);
+    if (!held) {
+        ViceLog(0, ("Failed malloc in h_Enumerate\n"));
+       assert(0);
+    }
     for (count = 0, host = hostList ; host ; host = host->next, count++) {
        list[count] = host;
        if (!(held[count] = h_Held_r(host)))
@@ -914,18 +869,17 @@ h_Enumerate(proc, param)
     free((void *)held);
 } /*h_Enumerate*/
 
-/* h_Enumerate_r: Calls (*proc)(host, held, param) for at least each host in
- * the at the start of the enumeration (perhaps more).  Hosts may be deleted
- * (have delete flag set); ditto for clients.  (*proc) is always called with
+/* h_Enumerate_r (revised):
+ * Calls (*proc)(host, held, param) for each host in hostList, starting
+ * at enumstart
+ * Hosts may be deleted (have delete flag set); ditto for clients.
+ * (*proc) is always called with
  * host h_held() and the global host lock (H_LOCK) locked.The hold state of the
  * host with respect to this lwp is passed to (*proc) as the param held.
  * The proc should return 0 if the host should be released, 1 if it should
  * be held after enumeration.
  */
-h_Enumerate_r(proc, param)
-    int (*proc)();
-    char *param;
-
+void h_Enumerate_r(int (*proc)(), struct host* enumstart, char *param)
 {
     register struct host *host;
     register int held;
@@ -933,20 +887,38 @@ h_Enumerate_r(proc, param)
     if (hostCount == 0) {
        return;
     }
-    for (host = hostList ; host ; host = host->next) {
+    for (host = enumstart ; host ; host = host->next) {
        if (!(held = h_Held_r(host)))
            h_Hold_r(host);
        held = (*proc)(host, held, param);
        if (!held)
            h_Release_r(host);/* this might free up the host */
     }
-} /*h_Enumerate*/
+} /*h_Enumerate_r*/
 
+/* inserts a new HashChain structure corresponding to this UUID */
+void hashInsertUuid_r(struct afsUUID *uuid, struct host* host)
+{
+       int index;
+       struct h_hashChain*     chain;
 
-/* Host is returned held */
-struct host *h_GetHost_r(tcon)
-    struct rx_connection *tcon;
+       /* hash into proper bucket */
+       index = h_UuidHashIndex(uuid);
 
+        /* insert into beginning of list for this bucket */
+       chain = (struct h_hashChain *)malloc(sizeof(struct h_hashChain));
+       if (!chain) {
+           ViceLog(0, ("Failed malloc in hashInsertUuid_r\n"));
+           assert(0);
+       }
+       assert(chain);
+       chain->hostPtr = host;
+       chain->next = hostUuidHashTable[index];
+       hostUuidHashTable[index] = chain;
+}
+
+/* Host is returned held */
+struct host *h_GetHost_r(struct rx_connection *tcon)
 {
     struct host *host;
     struct host *oldHost;
@@ -954,7 +926,6 @@ struct host *h_GetHost_r(tcon)
     int held;
     struct interfaceAddr interf;
     int interfValid = 0;
-    afs_int32  buffer[AFS_MAX_INTERFACE_ADDR];
     struct Identity *identP = NULL;
     afs_int32 haddr;
     afs_int32 hport;
@@ -987,7 +958,11 @@ retry:
        code = RXAFSCB_WhoAreYou(host->callback_rxcon, &interf);
        H_LOCK
        if ( code == RXGEN_OPCODE ) {
-               identP = (struct Identity *)malloc(1);
+               identP = (struct Identity *)malloc(sizeof(struct Identity));
+               if (!identP) {
+                   ViceLog(0, ("Failed malloc in h_GetHost_r\n"));
+                   assert(0);
+               }
                identP->valid = 0;
                rx_SetSpecific(tcon, rxcon_ident_key, identP);
                /* The host on this connection was unable to respond to 
@@ -1007,6 +982,10 @@ retry:
        } else if (code == 0) {
                interfValid = 1;
                identP = (struct Identity *)malloc(sizeof(struct Identity));
+               if (!identP) {
+                   ViceLog(0, ("Failed malloc in h_GetHost_r\n"));
+                   assert(0);
+               }
                identP->valid = 1;
                identP->uuid = interf.uuid;
                rx_SetSpecific(tcon, rxcon_ident_key, identP);
@@ -1052,19 +1031,27 @@ retry:
          && ( ( !identP->valid && host->interface )
            || ( identP->valid && !host->interface )
            || ( identP->valid
-             && !afs_uuid_equal(&identP->uuid, &host->interface->uuid) ) ) ) {
-               /* The host in the cache is not the host for this connection */
-               host->hostFlags |= HOSTDELETED;
-               h_Unlock_r(host);
-               if (!held) h_Release_r(host);
-               ViceLog(0, ("CB: new identity for host %s:%d, deleting\n",
-                          afs_inet_ntoa_r(host->host, hoststr), host->port));
-               goto retry;
+             && !afs_uuid_equal(&identP->uuid, &host->interface->uuid) ) ) ) 
+       {
+           char uuid1[128], uuid2[128];
+           /* The host in the cache is not the host for this connection */
+           host->hostFlags |= HOSTDELETED;
+           h_Unlock_r(host);
+           if (!held) h_Release_r(host);
+
+           if (identP->valid)
+               afsUUID_to_string(identP->uuid, uuid1, 127);
+           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), host->port, 
+                    identP->valid, host->interface, identP->valid ? uuid1 : 
+                    "", host->interface ? uuid2 : ""));
+           goto retry;
        }
     } else {
-        host = h_Alloc_r(tcon);
-        h_Hold_r(host);
-        h_Lock_r(host);
+       host = h_Alloc_r(tcon); /* returned held and locked */
        h_gethostcps_r(host,FT_ApproxTime());
         if (!(host->Console&1)) {
            if (!identP || !interfValid) {
@@ -1072,7 +1059,11 @@ retry:
                code = RXAFSCB_WhoAreYou(host->callback_rxcon, &interf);
                H_LOCK
                if ( code == RXGEN_OPCODE ) {
-                   identP = (struct Identity *)malloc(1);
+                   identP = (struct Identity *)malloc(sizeof(struct Identity));
+                   if (!identP) {
+                       ViceLog(0, ("Failed malloc in h_GetHost_r\n"));
+                       assert(0);
+                   }
                    identP->valid = 0;
                    rx_SetSpecific(tcon, rxcon_ident_key, identP);
                    ViceLog(25,
@@ -1082,6 +1073,10 @@ retry:
                } else if (code == 0) {
                    interfValid = 1;
                    identP = (struct Identity *)malloc(sizeof(struct Identity));
+                   if (!identP) {
+                       ViceLog(0, ("Failed malloc in h_GetHost_r\n"));
+                       assert(0);
+                   }
                    identP->valid = 1;
                    identP->uuid = interf.uuid;
                    rx_SetSpecific(tcon, rxcon_ident_key, identP);
@@ -1163,11 +1158,7 @@ void h_InitHostPackage()
 #endif /* AFS_PTHREAD_ENV */
 }
 
-static MapName_r(aname, acell, aval)
-    char *aname;
-    char *acell;
-    afs_int32 *aval;
-
+static int MapName_r(char *aname, char *acell, afs_int32 *aval)
 {
     namelist lnames;
     idlist lids;
@@ -1183,7 +1174,7 @@ static MapName_r(aname, acell, aval)
     lnames.namelist_len = 1;
     lnames.namelist_val = (prname *) aname;  /* don't malloc in the common case */
     lids.idlist_len = 0;
-    lids.idlist_val = (afs_int32 *) 0;
+    lids.idlist_val = NULL;
 
     cnamelen=strlen(acell);
     if (cnamelen) {
@@ -1198,6 +1189,10 @@ static MapName_r(aname, acell, aval)
            }               
            foreign = 1;  /* attempt cross-cell authentication */
            tname = (char *) malloc(anamelen+cnamelen+2);
+           if (!tname) {
+               ViceLog(0, ("Failed malloc in MapName_r\n"));
+               assert(0);
+           }
            strcpy(tname, aname);
            tname[anamelen] = '@';
            strcpy(tname+anamelen+1, acell);
@@ -1230,8 +1225,7 @@ static MapName_r(aname, acell, aval)
 
 
 /* NOTE: this returns the client with a Shared lock */
-struct client *h_ID2Client(vid)
-afs_int32 vid;
+struct client *h_ID2Client(afs_int32 vid)
 {
     register struct client *client;
     register struct host *host;
@@ -1255,7 +1249,7 @@ afs_int32 vid;
       }
 
     H_UNLOCK
-return 0;
+    return 0;
 }
 
 /*
@@ -1265,9 +1259,7 @@ return 0;
  * by one. The caller must call h_ReleaseClient_r when finished with
  * the client.
  */
-struct client *h_FindClient_r(tcon)
-    struct rx_connection *tcon;
-
+struct client *h_FindClient_r(struct rx_connection *tcon)
 {
     register struct client *client;
     register struct host *host;
@@ -1291,7 +1283,7 @@ ticket name length != 64
        h_Hold_r(client->host);
        if (client->prfail != 2) {  /* Could add shared lock on client here */
          /* note that we don't have to lock entry in this path to
-          * ensure CPS is initialized, since we don't call rxr_SetSpecific
+          * ensure CPS is initialized, since we don't call rx_SetSpecific
           * until initialization is done, and we only get here if
           * rx_GetSpecific located the client structure.
           */
@@ -1360,6 +1352,16 @@ ticket name length != 64
             if (client->tcon && (client->tcon != tcon)) {
                ViceLog(0, ("*** Vid=%d, sid=%x, tcon=%x, Tcon=%x ***\n", 
                            client->ViceId, client->sid, client->tcon, tcon));
+               oldClient = (struct client *) rx_GetSpecific(client->tcon,
+                                                            rxcon_client_key);
+               if (oldClient) {
+                   if (oldClient == client)
+                       rx_SetSpecific(client->tcon, rxcon_client_key, NULL);
+                   else
+                       ViceLog(0,
+                           ("Client-conn mismatch: CL1=%x, CN=%x, CL2=%x\n",
+                            client, client->tcon, oldClient));
+               }
                client->tcon = (struct rx_connection *)0;
             }
             client->refCount++;
@@ -1396,7 +1398,7 @@ ticket name length != 64
        if (client->CPS.prlist_val && (client->ViceId != ANONYMOUSID)) {
           free(client->CPS.prlist_val);
        }
-       client->CPS.prlist_val = (afs_int32 *)0;
+       client->CPS.prlist_val = NULL;
         client->ViceId = viceid;
        client->expTime = expTime;
 
@@ -1443,7 +1445,8 @@ ticket name length != 64
      * required).  So, before setting the RPC's rock, we should disconnect
      * the RPC from the other client structure's rock.
      */
-    if (oldClient = (struct client *) rx_GetSpecific(tcon, rxcon_client_key)) {
+    oldClient = (struct client *) rx_GetSpecific(tcon, rxcon_client_key);
+    if (oldClient && oldClient->tcon == tcon) {
        oldClient->tcon = (struct rx_connection *) 0;
        /* rx_SetSpecific will be done immediately below */
     }
@@ -1455,8 +1458,7 @@ ticket name length != 64
 
 } /*h_FindClient_r*/
 
-int h_ReleaseClient_r(client)
-    struct client *client;
+int h_ReleaseClient_r(struct client *client)
 {
     assert(client->refCount > 0);
     client->refCount--;
@@ -1471,18 +1473,22 @@ int h_ReleaseClient_r(client)
  * It does check tokens, since only the server routines can return the
  * VICETOKENDEAD error code
  */
-int GetClient(tcon, cp)
-    struct rx_connection * tcon;
-    struct client **cp;
-
+int GetClient(struct rx_connection * tcon, struct client **cp)
 {
     register struct client *client;
 
     H_LOCK
 
     *cp = client = (struct client *) rx_GetSpecific(tcon, rxcon_client_key);
-    /* XXXX debug */
-    assert(client && client->tcon && rxr_CidOf(client->tcon) == client->sid);
+    if (!(client && client->tcon && rxr_CidOf(client->tcon) == client->sid)) {
+       if (!client)
+           ViceLog(0, ("GetClient: no client in conn %x\n", tcon));
+       else
+           ViceLog(0, ("GetClient: tcon %x tcon sid %d client sid %d\n", 
+                       client->tcon, client->tcon ? rxr_CidOf(client->tcon)
+                       : -1, client->sid));
+       assert(0);
+    }
     if (client &&
        client->LastCall > client->expTime && client->expTime) {
        char hoststr[16];
@@ -1501,9 +1507,7 @@ int GetClient(tcon, cp)
 
 
 /* Client user name for short term use.  Note that this is NOT inexpensive */
-char *h_UserName(client)
-    struct client *client;
-
+char *h_UserName(struct client *client)
 {
     static char User[PR_MAXNAMELEN+1];
     namelist lnames;
@@ -1511,6 +1515,10 @@ char *h_UserName(client)
 
     lids.idlist_len = 1;
     lids.idlist_val = (afs_int32 *)malloc(1*sizeof(afs_int32));
+    if (!lids.idlist_val) {
+       ViceLog(0, ("Failed malloc in h_UserName\n"));
+       assert(0);
+    }
     lnames.namelist_len = 0;
     lnames.namelist_val = (prname *)0;
     lids.idlist_val[0] = client->ViceId;
@@ -1527,8 +1535,7 @@ char *h_UserName(client)
 } /*h_UserName*/
 
 
-h_PrintStats()
-
+void h_PrintStats()
 {
     ViceLog(0,
            ("Total Client entries = %d, blocks = %d; Host entries = %d, blocks = %d\n",
@@ -1537,10 +1544,8 @@ h_PrintStats()
 } /*h_PrintStats*/
 
 
-static int h_PrintClient(host, held, file)
-    register struct host *host;
-    int held;
-    StreamHandle_t *file;
+static int 
+h_PrintClient(register struct host *host, int held, StreamHandle_t *file)
 {
     register struct client *client;
     int i;
@@ -1597,8 +1602,7 @@ static int h_PrintClient(host, held, file)
  * Print a list of clients, with last security level and token value seen,
  * if known
  */
-h_PrintClients()
-
+void h_PrintClients()
 {
     time_t now;
     char tmpStr[256];
@@ -1622,11 +1626,8 @@ h_PrintClients()
 
 
 
-static int h_DumpHost(host, held, file)
-    register struct host *host;
-    int held;
-    StreamHandle_t *file;
-
+static int 
+h_DumpHost(register struct host *host, int held, StreamHandle_t *file)
 {
     int i;
     char tmpStr[256];
@@ -1667,8 +1668,7 @@ static int h_DumpHost(host, held, file)
 } /*h_DumpHost*/
 
 
-h_DumpHosts()
-
+void h_DumpHosts()
 {
     time_t now;
     StreamHandle_t *file = STREAM_OPEN(AFSDIR_SERVER_HOSTDUMP_FILEPATH, "w");
@@ -1696,12 +1696,8 @@ h_DumpHosts()
  * recently).  An active workstation has received a call since the cutoff
  * time argument passed.
  */
-h_GetWorkStats(nump, activep, delp, cutofftime)
-    int *nump;
-    int *activep;
-    int *delp;
-    afs_int32 cutofftime;
-
+void 
+h_GetWorkStats(int *nump, int *activep, int *delp, afs_int32 cutofftime)
 {
     register int i;
     register struct host *host;
@@ -1759,14 +1755,10 @@ h_GetWorkStats(nump, activep, delp, cutofftime)
  *     As advertised.
  *------------------------------------------------------------------------*/
 
-static void h_ClassifyAddress(a_targetAddr, a_candAddr, a_sameNetOrSubnetP,
-                      a_diffSubnetP, a_diffNetworkP)
-    afs_uint32 a_targetAddr;
-    afs_uint32 a_candAddr;
-    afs_int32 *a_sameNetOrSubnetP;
-    afs_int32 *a_diffSubnetP;
-    afs_int32 *a_diffNetworkP;
-
+static void h_ClassifyAddress(afs_uint32 a_targetAddr, afs_uint32 a_candAddr,
+                             afs_int32 *a_sameNetOrSubnetP, 
+                             afs_int32 *a_diffSubnetP, 
+                             afs_int32 *a_diffNetworkP)
 { /*h_ClassifyAddress*/
 
     register int i;                     /*Iterator thru host hash table*/
@@ -1875,13 +1867,8 @@ static void h_ClassifyAddress(a_targetAddr, a_candAddr, a_sameNetOrSubnetP,
  *     As advertised.
  *------------------------------------------------------------------------*/
 
-void h_GetHostNetStats(a_numHostsP, a_sameNetOrSubnetP, a_diffSubnetP,
-                      a_diffNetworkP)
-    afs_int32 *a_numHostsP;
-    afs_int32 *a_sameNetOrSubnetP;
-    afs_int32 *a_diffSubnetP;
-    afs_int32 *a_diffNetworkP;
-
+void h_GetHostNetStats(afs_int32 *a_numHostsP, afs_int32 *a_sameNetOrSubnetP,
+                      afs_int32 *a_diffSubnetP, afs_int32 *a_diffNetworkP)
 { /*h_GetHostNetStats*/
 
     register struct host *hostP;        /*Ptr to current host entry*/
@@ -1922,17 +1909,13 @@ static struct AFSFid zerofid;
 
 
 /*
- * XXXX: This routine could use Multi-R to avoid serializing the timeouts.
+ * XXXX: This routine could use Multi-Rx to avoid serializing the timeouts.
  * Since it can serialize them, and pile up, it should be a separate LWP
  * from other events.
  */
-int CheckHost(host, held)
-    register struct host *host;
-    int held;
-
+int CheckHost(register struct host *host, int held)
 {
     register struct client *client;
-    struct interfaceAddr interf;
     int code;
 
     /* Host is held by h_Enumerate */
@@ -2027,8 +2010,7 @@ int CheckHost(host, held)
  *
  * This routine is called roughly every 5 minutes.
  */
-h_CheckHosts() {
-
+void h_CheckHosts() {
     afs_uint32 now = FT_ApproxTime();
 
     memset((char *)&zerofid, 0, sizeof(zerofid));
@@ -2038,7 +2020,7 @@ h_CheckHosts() {
      */
     checktime = now - 15*60;
     clientdeletetime = now - 120*60;   /* 2 hours ago */
-    h_Enumerate(CheckHost, (char *) 0);
+    h_Enumerate(CheckHost, NULL);
 
 } /*h_CheckHosts*/
 
@@ -2051,9 +2033,7 @@ h_CheckHosts() {
  * The addresses in the ineterfaceAddr list are in host byte order.
  */
 int
-initInterfaceAddr_r(host, interf)
-struct host*   host;
-struct interfaceAddr *interf;
+initInterfaceAddr_r(struct host *host, struct interfaceAddr *interf)
 {
        int i, j;
        int number, count;
@@ -2068,11 +2048,11 @@ struct interfaceAddr *interf;
                host->host, interf->numberOfInterfaces));
 
        number = interf->numberOfInterfaces;
-       myPort   = host->port;
-       myHost   = host->host; /* current interface address */
+       myPort = host->port;
+       myHost = host->host; /* current interface address */
 
        /* validation checks */
-       if ( number < 0 )
+       if ( number < 0 || number > AFS_MAX_INTERFACE_ADDR )
         {
                ViceLog(0,("Number of alternate addresses returned is %d\n",
                         number));
@@ -2105,7 +2085,10 @@ struct interfaceAddr *interf;
            interface = (struct Interface *)
                        malloc(sizeof(struct Interface) +
                               (sizeof(afs_int32) * (count-1)));
-           assert(interface);
+           if (!interface) {
+               ViceLog(0, ("Failed malloc in initInterfaceAddr_r\n"));
+               assert(0);
+           }
            interface->numberOfInterfaces = count;
        } else {
            interface = (struct Interface *)
@@ -2130,6 +2113,28 @@ struct interfaceAddr *interf;
        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
@@ -2139,9 +2144,7 @@ struct interfaceAddr *interf;
  * All addresses are in network byte order.
  */
 int
-addInterfaceAddr_r(host, addr)
-struct host*   host;
-afs_int32 addr;
+addInterfaceAddr_r(struct host *host, afs_int32 addr)
 {
        int i;
        int number;
@@ -2168,6 +2171,10 @@ afs_int32 addr;
            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++)
@@ -2185,58 +2192,16 @@ afs_int32 addr;
        return 0;
 }
 
-/* inserts  a new HashChain structure corresponding to this address */
-hashInsert_r(addr, host)
-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));
-       assert(chain);
-       chain->hostPtr = host;
-       chain->next = hostHashTable[index];
-       chain->addr = addr;
-       hostHashTable[index] = chain;
-
-}
-
-/* inserts  a new HashChain structure corresponding to this UUID */
-hashInsertUuid_r(uuid, host)
-struct afsUUID *uuid;
-struct host* host;
-{
-       int index;
-       struct h_hashChain*     chain;
-
-       /* hash into proper bucket */
-       index = h_UuidHashIndex(uuid);
-
-        /* insert into beginning of list for this bucket */
-       chain = (struct h_hashChain *)malloc(sizeof(struct h_hashChain));
-       assert(chain);
-       chain->hostPtr = host;
-       chain->next = hostUuidHashTable[index];
-       hostUuidHashTable[index] = chain;
-}
-
 /* deleted a HashChain structure for this address and host */
 /* returns 1 on success */
 int
-hashDelete_r(addr, host)
-afs_int32 addr;
-struct host* host;
+hashDelete_r(afs_int32 addr, struct host* host)
 {
        int flag;
        int index;
        register struct h_hashChain **hp, *th;
 
-        for (hp = &hostHashTable[h_HashIndex(addr)]; th = *hp; )
+        for (hp = &hostHashTable[h_HashIndex(addr)]; (th = *hp); )
         {
                assert(th->hostPtr);
                if (th->hostPtr == host && th->addr == addr)
@@ -2257,9 +2222,8 @@ struct host* host;
 ** prints out all alternate interface address for the host. The 'level'
 ** parameter indicates what level of debugging sets this output
 */
-printInterfaceAddr(host, level)
-struct host*   host;
-int            level;
+void
+printInterfaceAddr(struct host *host, int level)
 {
        int i, number;
         if ( host-> interface )