From 7a6efc9bfcd955901d19274cc96f9a1b67f54f95 Mon Sep 17 00:00:00 2001 From: Andrew Deason Date: Fri, 17 Feb 2012 13:14:31 -0600 Subject: [PATCH] viced: Correctly update addrs on alt addr probe The functions MultiBreakCallBackAlternateAddress_r and MultiProbeAlternateAddress_r try to find a valid address in a host's interface list of addrs. If they find one, they update host->host and host->port. However, they do so just by changing those fields directly and by calling h_DeleteHostFromAddrHashTable_r and h_AddHostToAddrHashTable_r. This leaves the old host->host, host->port on the interface list, and leaves it marked as 'valid'. Similarly, the new host and port may still be marked as not 'valid'. This can result in the host being on the addr hash table via an address that is not on the host's interface list. After the above situation occurs, we may call removeInterfaceAddr_r(host, host->host, host->port); and then update host->host and host->port, which happens in a variety of places. Since host->host, host->port is not marked as valid in the interface list, it is not removed from the addr hash table, but it is removed from the interface list. Eventually, this can cause the host to be referenced from the addr hash table even after it has been freed. Since this can result in hash table entries pointing to the 'wrong' host, this can result in FileLog messages such as: Sun Feb 5 03:16:35 2012 Removing address that does not belong to host 0xdeadbeefdead (1.2.3.4:7001). And bogus instances of the message: Sun Feb 5 03:16:36 2012 CB: new identity for host 0xdeadbeefdead (1.2.3.4:7001), deleting(1 baadcafe 12345678-9abc-def0-12-34-456789abcdef fedcba98-76543210f-ed-cb-a9876543210f) To fix this, make MultiBreakCallBackAlternateAddress_r and MultiProbeAlternateAddress_r update the address list the same way as all of the code in host.c does; by adding the new address with addInterfaceAddr_r, removing it with removeInterfaceAddr_r, and updating host->host and host->port. Change-Id: I0a95e0186c03c1831c4df86daae901bf2462da0e Reviewed-on: http://gerrit.openafs.org/6727 Reviewed-by: Jeffrey Altman Reviewed-by: Alistair Ferguson Reviewed-by: Derrick Brashear Tested-by: BuildBot --- src/viced/callback.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/viced/callback.c b/src/viced/callback.c index a4fb613443..b6e33733e5 100644 --- a/src/viced/callback.c +++ b/src/viced/callback.c @@ -3004,10 +3004,12 @@ MultiBreakCallBackAlternateAddress_r(struct host *host, if (host->callback_rxcon) rx_DestroyConnection(host->callback_rxcon); host->callback_rxcon = conns[multi_i]; - h_DeleteHostFromAddrHashTable_r(host->host, host->port, host); + /* add then remove */ + addInterfaceAddr_r(host, interfaces[multi_i].addr, + interfaces[multi_i].port); + removeInterfaceAddr_r(host, host->host, host->port); host->host = interfaces[multi_i].addr; host->port = interfaces[multi_i].port; - h_AddHostToAddrHashTable_r(host->host, host->port, host); connSuccess = conns[multi_i]; rx_SetConnDeadTime(host->callback_rxcon, 50); rx_SetConnHardDeadTime(host->callback_rxcon, AFS_HARDDEADTIME); @@ -3100,10 +3102,12 @@ MultiProbeAlternateAddress_r(struct host *host) if (host->callback_rxcon) rx_DestroyConnection(host->callback_rxcon); host->callback_rxcon = conns[multi_i]; - h_DeleteHostFromAddrHashTable_r(host->host, host->port, host); + /* add then remove */ + addInterfaceAddr_r(host, interfaces[multi_i].addr, + interfaces[multi_i].port); + removeInterfaceAddr_r(host, host->host, host->port); host->host = interfaces[multi_i].addr; host->port = interfaces[multi_i].port; - h_AddHostToAddrHashTable_r(host->host, host->port, host); connSuccess = conns[multi_i]; rx_SetConnDeadTime(host->callback_rxcon, 50); rx_SetConnHardDeadTime(host->callback_rxcon, AFS_HARDDEADTIME);