rx: RX_INVALID_OPERATION abort unknown service only
authorJeffrey Altman <jaltman@your-file-system.com>
Sun, 25 Nov 2012 00:47:01 +0000 (19:47 -0500)
committerDerrick Brashear <shadow@your-file-system.com>
Wed, 5 Dec 2012 18:46:44 +0000 (10:46 -0800)
Patchset 1fbe83f9aacfc36a9c426ba1fd18ad7c72869dc1 introduced the
sending of RX_INVALID_OPERATION aborts for connection attempts
requesting a service not offered by the rx peer.  By sending aborts
for all failures of rxi_FindConnection() the set of incoming packets
that are responded to is broader than simply those with non-matching
serviceIds.  This patchset restricts the transmission of
RX_INVALID_OPERATION aborts only to the explicit case in which
rxi_FindConnection() attempted to find a service and either failed
to find a match or couldn't apply the requested security class/level
to that service.

Change-Id: Ie18798531e542e54878209ccd2fbbcd24f31abb6
Reviewed-on: http://gerrit.openafs.org/8512
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@your-file-system.com>

src/rx/rx.c

index fed35c8..2e30dfc 100644 (file)
@@ -125,7 +125,8 @@ static void rxi_AckAll(struct rx_call *call);
 static struct rx_connection
        *rxi_FindConnection(osi_socket socket, afs_uint32 host, u_short port,
                            u_short serviceId, afs_uint32 cid,
-                           afs_uint32 epoch, int type, u_int securityIndex);
+                           afs_uint32 epoch, int type, u_int securityIndex,
+                            int *unknownService);
 static struct rx_packet
        *rxi_ReceiveDataPacket(struct rx_call *call, struct rx_packet *np,
                               int istack, osi_socket socket,
@@ -3125,10 +3126,12 @@ rxi_FindPeer(afs_uint32 host, u_short port, int create)
 static struct rx_connection *
 rxi_FindConnection(osi_socket socket, afs_uint32 host,
                   u_short port, u_short serviceId, afs_uint32 cid,
-                  afs_uint32 epoch, int type, u_int securityIndex)
+                  afs_uint32 epoch, int type, u_int securityIndex,
+                   int *unknownService)
 {
     int hashindex, flag, i;
     struct rx_connection *conn;
+    *unknownService = 0;
     hashindex = CONN_HASH(host, port, cid, epoch, type);
     MUTEX_ENTER(&rx_connHashTable_lock);
     rxLastConn ? (conn = rxLastConn, flag = 0) : (conn =
@@ -3173,6 +3176,7 @@ rxi_FindConnection(osi_socket socket, afs_uint32 host,
        if (!service || (securityIndex >= service->nSecurityObjects)
            || (service->securityObjects[securityIndex] == 0)) {
            MUTEX_EXIT(&rx_connHashTable_lock);
+            *unknownService = 1;
            return (struct rx_connection *)0;
        }
        conn = rxi_AllocConnection();   /* This bzero's the connection */
@@ -3470,6 +3474,7 @@ rxi_ReceivePacket(struct rx_packet *np, osi_socket socket,
     struct rx_call *call;
     struct rx_connection *conn;
     int type;
+    int unknownService = 0;
 #ifdef RXDEBUG
     char *packetType;
 #endif
@@ -3550,12 +3555,12 @@ rxi_ReceivePacket(struct rx_packet *np, osi_socket socket,
     conn =
        rxi_FindConnection(socket, host, port, np->header.serviceId,
                           np->header.cid, np->header.epoch, type,
-                          np->header.securityIndex);
+                          np->header.securityIndex, &unknownService);
 
     /* To avoid having 2 connections just abort at each other,
        don't abort an abort. */
     if (!conn) {
-        if (np->header.type != RX_PACKET_TYPE_ABORT)
+        if (unknownService && (np->header.type != RX_PACKET_TYPE_ABORT))
             rxi_SendRawAbort(socket, host, port, RX_INVALID_OPERATION,
                              np, 0);
         return np;