rx: Handle negative returns on packet reads
[openafs.git] / src / rx / rx_packet.c
index 69ccd66..78d2e5e 100644 (file)
 #  include "rx_kmutex.h"
 # endif /* defined(UKERNEL) */
 #else /* KERNEL */
-# include <sys/types.h>
-# include <sys/stat.h>
-# include <errno.h>
-# include <stdlib.h>
+# include <roken.h>
 # include <assert.h>
-# include <string.h>
-# ifdef HAVE_UNISTD_H
-#  include <unistd.h>
-# endif
 # if defined(AFS_NT40_ENV)
-#  include <winsock2.h>
 #  ifndef EWOULDBLOCK
 #   define EWOULDBLOCK WSAEWOULDBLOCK
 #  endif
 #  include "rx_user.h"
 #  include "rx_xmit_nt.h"
-# else
-#  include <sys/socket.h>
-#  include <netinet/in.h>
 # endif
 # include <lwp.h>
 #endif /* KERNEL */
@@ -77,6 +66,9 @@
 #include "rx_internal.h"
 #include "rx_stats.h"
 
+#include "rx_conn.h"
+#include "rx_call.h"
+
 #ifdef RX_LOCKS_DB
 /* rxdb_fileID is used to identify the lock location, along with line#. */
 static int rxdb_fileID = RXDB_FILE_RX_PACKET;
@@ -1356,9 +1348,7 @@ rxi_AllocSendPacket(struct rx_call *call, int want)
         * just wait.  */
        NETPRI;
        call->flags |= RX_CALL_WAIT_PACKETS;
-        MUTEX_ENTER(&rx_refcnt_mutex);
        CALL_HOLD(call, RX_CALL_REFCOUNT_PACKET);
-        MUTEX_EXIT(&rx_refcnt_mutex);
        MUTEX_EXIT(&call->lock);
        rx_waitingForPackets = 1;
 
@@ -1369,9 +1359,7 @@ rxi_AllocSendPacket(struct rx_call *call, int want)
 #endif
        MUTEX_EXIT(&rx_freePktQ_lock);
        MUTEX_ENTER(&call->lock);
-        MUTEX_ENTER(&rx_refcnt_mutex);
        CALL_RELE(call, RX_CALL_REFCOUNT_PACKET);
-        MUTEX_EXIT(&rx_refcnt_mutex);
        call->flags &= ~RX_CALL_WAIT_PACKETS;
        USERPRI;
     }
@@ -1419,7 +1407,7 @@ rxi_ReadPacket(osi_socket socket, struct rx_packet *p, afs_uint32 * host,
               u_short * port)
 {
     struct sockaddr_in from;
-    unsigned int nbytes;
+    int nbytes;
     afs_int32 rlen;
     afs_uint32 tlen, savelen;
     struct msghdr msg;
@@ -1458,7 +1446,7 @@ rxi_ReadPacket(osi_socket socket, struct rx_packet *p, afs_uint32 * host,
     p->wirevec[p->niovecs - 1].iov_len = savelen;
 
     p->length = (u_short)(nbytes - RX_HEADER_SIZE);
-    if ((nbytes > tlen) || (p->length & 0x8000)) {     /* Bogus packet */
+    if (nbytes < 0 || (nbytes > tlen) || (p->length & 0x8000)) { /* Bogus packet */
        if (nbytes < 0 && errno == EWOULDBLOCK) {
             if (rx_stats_active)
                 rx_atomic_inc(&rx_stats.noPacketOnRead);
@@ -1746,6 +1734,10 @@ m_cpytoiovec(struct mbuf *m, int off, int len, struct iovec iovs[], int niovs)
 #endif /* AFS_SUN5_ENV */
 
 #if !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN80_ENV)
+#if defined(AFS_NBSD_ENV)
+int
+rx_mb_to_packet(struct mbuf *amb, void (*free) (struct mbuf *), int hdr_len, int data_len, struct rx_packet *phandle)
+#else
 int
 rx_mb_to_packet(amb, free, hdr_len, data_len, phandle)
 #if defined(AFS_SUN5_ENV) || defined(AFS_HPUX110_ENV)
@@ -1756,6 +1748,7 @@ rx_mb_to_packet(amb, free, hdr_len, data_len, phandle)
      void (*free) ();
      struct rx_packet *phandle;
      int hdr_len, data_len;
+#endif /* AFS_NBSD_ENV */
 {
     int code;
 
@@ -1992,13 +1985,10 @@ rxi_ReceiveDebugPacket(struct rx_packet *ap, osi_socket asocket,
                        tpeer.burstWait.usec = htonl(tp->burstWait.usec);
                        tpeer.rtt = htonl(tp->rtt);
                        tpeer.rtt_dev = htonl(tp->rtt_dev);
-                       tpeer.timeout.sec = htonl(tp->timeout.sec);
-                       tpeer.timeout.usec = htonl(tp->timeout.usec);
                        tpeer.nSent = htonl(tp->nSent);
                        tpeer.reSends = htonl(tp->reSends);
                        tpeer.inPacketSkew = htonl(tp->inPacketSkew);
                        tpeer.outPacketSkew = htonl(tp->outPacketSkew);
-                       tpeer.rateFlag = htonl(tp->rateFlag);
                        tpeer.natMTU = htons(tp->natMTU);
                        tpeer.maxMTU = htons(tp->maxMTU);
                        tpeer.maxDgramPackets = htons(tp->maxDgramPackets);
@@ -2287,9 +2277,8 @@ rxi_SendPacket(struct rx_call *call, struct rx_connection *conn,
            /* send failed, so let's hurry up the resend, eh? */
             if (rx_stats_active)
                 rx_atomic_inc(&rx_stats.netSendFailures);
-           p->retryTime = p->timeSent; /* resend it very soon */
-           clock_Addmsec(&(p->retryTime),
-                         10 + (((afs_uint32) p->backoff) << 8));
+           p->flags &= ~RX_PKTFLAG_SENT; /* resend it very soon */
+
            /* Some systems are nice and tell us right away that we cannot
             * reach this recipient by returning an error code.
             * So, when this happens let's "down" the host NOW so
@@ -2324,10 +2313,10 @@ rxi_SendPacket(struct rx_call *call, struct rx_connection *conn,
 #endif
 #ifdef RXDEBUG
     }
-    dpf(("%c %d %s: %x.%u.%u.%u.%u.%u.%u flags %d, packet %"AFS_PTR_FMT" resend %d.%.3d len %d\n",
+    dpf(("%c %d %s: %x.%u.%u.%u.%u.%u.%u flags %d, packet %"AFS_PTR_FMT" len %d\n",
           deliveryType, p->header.serial, rx_packetTypes[p->header.type - 1], ntohl(peer->host),
           ntohs(peer->port), p->header.serial, p->header.epoch, p->header.cid, p->header.callNumber,
-          p->header.seq, p->header.flags, p, p->retryTime.sec, p->retryTime.usec / 1000, p->length));
+          p->header.seq, p->header.flags, p, p->length));
 #endif
     if (rx_stats_active) {
         rx_atomic_inc(&rx_stats.packetsSent[p->header.type - 1]);
@@ -2498,9 +2487,7 @@ rxi_SendPacketList(struct rx_call *call, struct rx_connection *conn,
                 rx_atomic_inc(&rx_stats.netSendFailures);
            for (i = 0; i < len; i++) {
                p = list[i];
-               p->retryTime = p->timeSent;     /* resend it very soon */
-               clock_Addmsec(&(p->retryTime),
-                             10 + (((afs_uint32) p->backoff) << 8));
+               p->flags &= ~RX_PKTFLAG_SENT;  /* resend it very soon */
            }
            /* Some systems are nice and tell us right away that we cannot
             * reach this recipient by returning an error code.
@@ -2529,10 +2516,10 @@ rxi_SendPacketList(struct rx_call *call, struct rx_connection *conn,
 
     osi_Assert(p != NULL);
 
-    dpf(("%c %d %s: %x.%u.%u.%u.%u.%u.%u flags %d, packet %"AFS_PTR_FMT" resend %d.%.3d len %d\n",
+    dpf(("%c %d %s: %x.%u.%u.%u.%u.%u.%u flags %d, packet %"AFS_PTR_FMT" len %d\n",
           deliveryType, p->header.serial, rx_packetTypes[p->header.type - 1], ntohl(peer->host),
           ntohs(peer->port), p->header.serial, p->header.epoch, p->header.cid, p->header.callNumber,
-          p->header.seq, p->header.flags, p, p->retryTime.sec, p->retryTime.usec / 1000, p->length));
+          p->header.seq, p->header.flags, p, p->length));
 
 #endif
     if (rx_stats_active) {
@@ -2705,7 +2692,8 @@ rxi_PrepareSendPacket(struct rx_call *call,
        *call->callNumber = 1;
 
     MUTEX_EXIT(&call->lock);
-    p->flags &= ~RX_PKTFLAG_ACKED;
+    p->flags &= ~(RX_PKTFLAG_ACKED | RX_PKTFLAG_SENT);
+
     p->header.cid = (conn->cid | call->channel);
     p->header.serviceId = conn->serviceId;
     p->header.securityIndex = conn->securityIndex;
@@ -2722,10 +2710,8 @@ rxi_PrepareSendPacket(struct rx_call *call,
     if (last)
        p->header.flags |= RX_LAST_PACKET;
 
-    clock_Zero(&p->retryTime); /* Never yet transmitted */
     clock_Zero(&p->firstSent); /* Never yet transmitted */
     p->header.serial = 0;      /* Another way of saying never transmitted... */
-    p->backoff = 0;
 
     /* Now that we're sure this is the last data on the call, make sure
      * that the "length" and the sum of the iov_lens matches. */
@@ -2750,8 +2736,8 @@ rxi_PrepareSendPacket(struct rx_call *call,
     }
     if (len)
         p->wirevec[i - 1].iov_len += len;
-    RXS_PreparePacket(conn->securityObject, call, p);
     MUTEX_ENTER(&call->lock);
+    RXS_PreparePacket(conn->securityObject, call, p);
 }
 
 /* Given an interface MTU size, calculate an adjusted MTU size that
@@ -2837,9 +2823,9 @@ int rx_DumpPackets(FILE *outputFile, char *cookie)
 #endif
 
     for (p = rx_mallocedP; p; p = p->allNextp) {
-        RXDPRINTF(RXDPRINTOUT, "%s - packet=0x%p, id=%u, firstSent=%u.%08u, timeSent=%u.%08u, retryTime=%u.%08u, firstSerial=%u, niovecs=%u, flags=0x%x, backoff=%u, length=%u  header: epoch=%u, cid=%u, callNum=%u, seq=%u, serial=%u, type=%u, flags=0x%x, userStatus=%u, securityIndex=%u, serviceId=%u\r\n",
-                cookie, p, p->packetId, p->firstSent.sec, p->firstSent.usec, p->timeSent.sec, p->timeSent.usec, p->retryTime.sec, p->retryTime.usec,
-                p->firstSerial, p->niovecs, (afs_uint32)p->flags, (afs_uint32)p->backoff, (afs_uint32)p->length,
+        RXDPRINTF(RXDPRINTOUT, "%s - packet=0x%p, id=%u, firstSent=%u.%08u, timeSent=%u.%08u, firstSerial=%u, niovecs=%u, flags=0x%x, length=%u  header: epoch=%u, cid=%u, callNum=%u, seq=%u, serial=%u, type=%u, flags=0x%x, userStatus=%u, securityIndex=%u, serviceId=%u\r\n",
+                cookie, p, p->packetId, p->firstSent.sec, p->firstSent.usec, p->timeSent.sec, p->timeSent.usec,
+                p->firstSerial, p->niovecs, (afs_uint32)p->flags, (afs_uint32)p->length,
                 p->header.epoch, p->header.cid, p->header.callNumber, p->header.seq, p->header.serial,
                 (afs_uint32)p->header.type, (afs_uint32)p->header.flags, (afs_uint32)p->header.userStatus,
                 (afs_uint32)p->header.securityIndex, (afs_uint32)p->header.serviceId);