From: Derrick Brashear Date: Thu, 25 Feb 2010 03:34:28 +0000 (-0500) Subject: rx lowlevel nat ping X-Git-Tag: openafs-devel-1_5_73~122 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=d24078658d183ea2e72e61c1888e9900bac0ec32;p=packages%2Fo%2Fopenafs.git rx lowlevel nat ping for rfc 4787, do a minimal impact nat ping. this uses an rx "version request" reply debug packet, which will simply be discarded by the receiver, to keep the port mapping open. Change-Id: Ic2180bfa5c467e33c72e3f19d62488bd6a2dc61a Reviewed-on: http://gerrit.openafs.org/1393 Reviewed-by: Simon Wilkinson Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear --- diff --git a/src/afs/afs_conn.c b/src/afs/afs_conn.c index d2091db49..eae56ff90 100644 --- a/src/afs/afs_conn.c +++ b/src/afs/afs_conn.c @@ -294,6 +294,8 @@ afs_ConnBySA(struct srvAddr *sap, unsigned short aport, afs_int32 acell, } rx_SetConnIdleDeadTime(tc->id, afs_rx_idledead); + rx_SetConnSecondsUntilNatPing(tc->id, 20); + tc->forceConnectFS = 0; /* apparently we're appropriately connected now */ if (csec) rxs_Release(csec); diff --git a/src/rx/rx.c b/src/rx/rx.c index 33c422b70..1d0d922f2 100755 --- a/src/rx/rx.c +++ b/src/rx/rx.c @@ -828,6 +828,7 @@ rx_NewConnection(afs_uint32 shost, u_short sport, u_short sservice, conn->securityData = (void *) 0; conn->securityIndex = serviceSecurityIndex; rx_SetConnDeadTime(conn, rx_connDeadTime); + rx_SetConnSecondsUntilNatPing(conn, 0); conn->ackRate = RX_FAST_ACK_RATE; conn->nSpecific = 0; conn->specific = NULL; @@ -1034,6 +1035,10 @@ rxi_DestroyConnectionNoLock(struct rx_connection *conn) return; } + if (conn->natKeepAliveEvent) { + rxi_NatKeepAliveOff(conn); + } + if (conn->delayedAbortEvent) { rxevent_Cancel(conn->delayedAbortEvent, (struct rx_call *)0, 0); packet = rxi_AllocPacket(RX_PACKET_CLASS_SPECIAL); @@ -1067,6 +1072,8 @@ rxi_DestroyConnectionNoLock(struct rx_connection *conn) rxevent_Cancel(conn->challengeEvent, (struct rx_call *)0, 0); if (conn->checkReachEvent) rxevent_Cancel(conn->checkReachEvent, (struct rx_call *)0, 0); + if (conn->natKeepAliveEvent) + rxevent_Cancel(conn->natKeepAliveEvent, (struct rx_call *)0, 0); /* Add the connection to the list of destroyed connections that * need to be cleaned up. This is necessary to avoid deadlocks @@ -4602,6 +4609,8 @@ rxi_ConnectionError(struct rx_connection *conn, MUTEX_ENTER(&conn->conn_data_lock); if (conn->challengeEvent) rxevent_Cancel(conn->challengeEvent, (struct rx_call *)0, 0); + if (conn->natKeepAliveEvent) + rxevent_Cancel(conn->natKeepAliveEvent, (struct rx_call *)0, 0); if (conn->checkReachEvent) { rxevent_Cancel(conn->checkReachEvent, (struct rx_call *)0, 0); conn->checkReachEvent = 0; @@ -5779,6 +5788,79 @@ rxi_CheckCall(struct rx_call *call) return 0; } +void +rxi_NatKeepAliveEvent(struct rxevent *event, void *arg1, void *dummy) +{ + struct rx_connection *conn = arg1; + struct rx_header theader; + char tbuffer[1500]; + struct sockaddr_in taddr; + char *tp; + char a[1] = { 0 }; + struct iovec tmpiov[2]; + osi_socket socket = + (conn->type == + RX_CLIENT_CONNECTION ? rx_socket : conn->service->socket); + + + MUTEX_ENTER(&conn->conn_data_lock); + conn->natKeepAliveEvent = NULL; + MUTEX_EXIT(&conn->conn_data_lock); + + tp = &tbuffer[sizeof(struct rx_header)]; + taddr.sin_family = AF_INET; + taddr.sin_port = rx_PortOf(rx_PeerOf(conn)); + taddr.sin_addr.s_addr = rx_HostOf(rx_PeerOf(conn)); +#ifdef STRUCT_SOCKADDR_HAS_SA_LEN + taddr.sin_len = sizeof(struct sockaddr_in); +#endif + memset(&theader, 0, sizeof(theader)); + theader.epoch = htonl(999); + theader.cid = 0; + theader.callNumber = 0; + theader.seq = 0; + theader.serial = 0; + theader.type = RX_PACKET_TYPE_VERSION; + theader.flags = RX_LAST_PACKET; + theader.serviceId = 0; + + memcpy(tbuffer, &theader, sizeof(theader)); + memcpy(tp, &a, sizeof(a)); + tmpiov[0].iov_base = tbuffer; + tmpiov[0].iov_len = 1 + sizeof(struct rx_header); + + osi_NetSend(socket, &taddr, tmpiov, 1, 1 + sizeof(struct rx_header), 1); + rxi_ScheduleNatKeepAliveEvent(conn); +} + +void +rxi_ScheduleNatKeepAliveEvent(struct rx_connection *conn) +{ + MUTEX_ENTER(&conn->conn_data_lock); + if (!conn->natKeepAliveEvent && conn->secondsUntilNatPing) { + struct clock when, now; + clock_GetTime(&now); + when = now; + when.sec += conn->secondsUntilNatPing; + conn->natKeepAliveEvent = + rxevent_PostNow(&when, &now, rxi_NatKeepAliveEvent, conn, 0); + } + MUTEX_EXIT(&conn->conn_data_lock); +} + +void +rx_SetConnSecondsUntilNatPing(struct rx_connection *conn, afs_int32 seconds) +{ + conn->secondsUntilNatPing = seconds; + if (seconds != 0) + rxi_ScheduleNatKeepAliveEvent(conn); +} + +void +rxi_NatKeepAliveOn(struct rx_connection *conn) +{ + rxi_ScheduleNatKeepAliveEvent(conn); +} /* When a call is in progress, this routine is called occasionally to * make sure that some traffic has arrived (or been sent to) the peer. diff --git a/src/rx/rx.h b/src/rx/rx.h index 8f7908676..9e3b1114d 100644 --- a/src/rx/rx.h +++ b/src/rx/rx.h @@ -272,6 +272,8 @@ struct rx_connection { u_char ackRate; /* how many packets between ack requests */ u_char makeCallWaiters; /* how many rx_NewCalls are waiting */ afs_int32 idleDeadErr; + afs_int32 secondsUntilNatPing; /* how often to ping conn */ + struct rxevent *natKeepAliveEvent; /* Scheduled to keep connection open */ int nSpecific; /* number entries in specific data */ void **specific; /* pointer to connection specific data */ }; diff --git a/src/rx/rx_globals.h b/src/rx/rx_globals.h index 78020fb15..a265ba1c7 100644 --- a/src/rx/rx_globals.h +++ b/src/rx/rx_globals.h @@ -531,6 +531,7 @@ EXT afs_kmutex_t rx_connHashTable_lock; /* Forward definitions of internal procedures */ #define rxi_ChallengeOff(conn) rxevent_Cancel((conn)->challengeEvent, (struct rx_call*)0, 0); #define rxi_KeepAliveOff(call) rxevent_Cancel((call)->keepAliveEvent, call, RX_CALL_REFCOUNT_ALIVE) +#define rxi_NatKeepAliveOff(conn) rxevent_Cancel((conn)->natKeepAliveEvent, (struct rx_call*)0, 0) #define rxi_AllocSecurityObject() (struct rx_securityClass *) rxi_Alloc(sizeof(struct rx_securityClass)) #define rxi_FreeSecurityObject(obj) rxi_Free(obj, sizeof(struct rx_securityClass)) diff --git a/src/rx/rx_prototypes.h b/src/rx/rx_prototypes.h index 35020be86..f7f3b3af0 100644 --- a/src/rx/rx_prototypes.h +++ b/src/rx/rx_prototypes.h @@ -169,7 +169,10 @@ extern void rxi_KeepAliveEvent(struct rxevent *event, void *call /* struct rx_call *call */, void *dummy); extern void rxi_ScheduleKeepAliveEvent(struct rx_call *call); +extern void rxi_ScheduleNatKeepAliveEvent(struct rx_connection *conn); extern void rxi_KeepAliveOn(struct rx_call *call); +extern void rxi_NatKeepAliveOn(struct rx_connection *conn); +extern void rx_SetConnSecondsUntilNatPing(struct rx_connection *conn, afs_int32 seconds); extern void rxi_SendDelayedConnAbort(struct rxevent *event, void *conn, /* struct rx_connection *conn */ void *dummy);