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 <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@dementix.org>
This commit is contained in:
Derrick Brashear 2012-02-12 22:45:59 -05:00
parent 4ed91fe594
commit 2378895fc6
3 changed files with 28 additions and 9 deletions

View File

@ -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 */

View File

@ -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)

View File

@ -1888,6 +1888,7 @@ afs_RemoveAllConns(void)
if (sa->conns) {
afs_ReleaseConns(sa->conns);
sa->conns = NULL;
sa->natping = NULL;
}
}
}