From 2378895fc66a19a050f302711f2e18dbbf2e3d6f Mon Sep 17 00:00:00 2001 From: Derrick Brashear Date: Sun, 12 Feb 2012 22:45:59 -0500 Subject: [PATCH] libafs: ensure one nat ping connection per srvAddr track the natping conn with the srvAddr, ensuring exactly one. Change-Id: I2e424a71d398563f9d0ec3ca77b83320cbef4ea1 Reviewed-on: http://gerrit.openafs.org/6706 Tested-by: BuildBot Reviewed-by: Derrick Brashear --- src/afs/afs.h | 1 + src/afs/afs_conn.c | 35 ++++++++++++++++++++++++++--------- src/afs/afs_server.c | 1 + 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/afs/afs.h b/src/afs/afs.h index 9a396a4d15..dd45066ef9 100644 --- a/src/afs/afs.h +++ b/src/afs/afs.h @@ -440,6 +440,7 @@ struct srvAddr { struct srvAddr *next_sa; /* another interface on same host */ struct server *server; /* back to parent */ struct sa_conn_vector *conns; /* All user connections to this server */ + struct afs_conn *natping; afs_int32 sa_ip; /* Host addr in network byte order */ u_short sa_iprank; /* indiv ip address priority */ u_short sa_portal; /* port addr in network byte order */ diff --git a/src/afs/afs_conn.c b/src/afs/afs_conn.c index 0bfb5262e8..09d7d8f04c 100644 --- a/src/afs/afs_conn.c +++ b/src/afs/afs_conn.c @@ -134,7 +134,7 @@ release_conns_user_server(struct unixuser *xu, struct server *xs) int cix, glocked; struct srvAddr *sa; struct afs_conn *tc; - struct sa_conn_vector *tcv, **lcv; + struct sa_conn_vector *tcv, **lcv, *tcvn; for (sa = (xs)->addr; sa; sa = sa->next_sa) { lcv = &sa->conns; for (tcv = *lcv; tcv; lcv = &tcv->next, tcv = *lcv) { @@ -149,6 +149,23 @@ release_conns_user_server(struct unixuser *xu, struct server *xs) if (tc->activated) { rx_SetConnSecondsUntilNatPing(tc->id, 0); rx_DestroyConnection(tc->id); + /* find another eligible connection */ + if (sa->natping == tc) { + int cin; + struct afs_conn *tcn; + for (tcvn = sa->conns; tcvn; tcvn = tcvn->next) { + if (tcvn == tcv) + continue; + for(cin = 0; cin < CVEC_LEN; ++cin) { + tcn = &(tcvn->cvec[cin]); + if (tcn->activated) { + rx_SetConnSecondsUntilNatPing(tcn->id, 20); + sa->natping = tcn; + break; + } + } + } + } } } if (glocked) @@ -180,6 +197,8 @@ release_conns_vector(struct sa_conn_vector *xcv) if (tc->activated) { rx_SetConnSecondsUntilNatPing(tc->id, 0); rx_DestroyConnection(tc->id); + if (tcv->srvr->natping == tc) + tcv->srvr->natping = NULL; } } if (glocked) @@ -450,6 +469,8 @@ afs_ConnBySA(struct srvAddr *sap, unsigned short aport, afs_int32 acell, UpgradeSToWLock(&afs_xconn, 38); csec = (struct rx_securityClass *)0; if (tc->id) { + if (sap->natping == tc) + sap->natping = NULL; if (glocked) AFS_GUNLOCK(); rx_SetConnSecondsUntilNatPing(tc->id, 0); @@ -485,16 +506,12 @@ afs_ConnBySA(struct srvAddr *sap, unsigned short aport, afs_int32 acell, rx_SetConnIdleDeadTime(tc->id, afs_rx_idledead); /* - * Only do this for the base connection, not per-user. - * Will need to be revisited if/when CB gets security. + * Only do this for one connection */ - if ((isec == 0) && (service != 52) && !(tu->states & UTokensBad) && - (tu->viceId == UNDEFVID) && (isrep == 0) -#ifndef UKERNEL /* ukernel runs as just one uid anyway */ - && (tu->uid == 0) -#endif - ) + if ((service != 52) && (sap->natping == NULL)) { + sap->natping = tc; rx_SetConnSecondsUntilNatPing(tc->id, 20); + } tc->forceConnectFS = 0; /* apparently we're appropriately connected now */ if (csec) diff --git a/src/afs/afs_server.c b/src/afs/afs_server.c index 44f0f4e261..f774ae274b 100644 --- a/src/afs/afs_server.c +++ b/src/afs/afs_server.c @@ -1888,6 +1888,7 @@ afs_RemoveAllConns(void) if (sa->conns) { afs_ReleaseConns(sa->conns); sa->conns = NULL; + sa->natping = NULL; } } }