disable Rx packet tracking
[openafs.git] / src / rx / rx_packet.c
index 707e308..92aef61 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright 2000, International Business Machines Corporation and others.
  * All Rights Reserved.
- * 
+ *
  * This software has been released under the terms of the IBM Public
  * License.  For details, see the LICENSE file in the top-level source
  * directory or online at http://www.openafs.org/dl/license10.html
@@ -101,15 +101,16 @@ extern char cml_version_number[];
 static int AllocPacketBufs(int class, int num_pkts, struct rx_queue *q);
 
 static void rxi_SendDebugPacket(struct rx_packet *apacket, osi_socket asocket,
-                               afs_int32 ahost, short aport,
+                               afs_uint32 ahost, short aport,
                                afs_int32 istack);
 
-static int rxi_FreeDataBufsToQueue(struct rx_packet *p, 
-                                  afs_uint32 first, 
-                                  struct rx_queue * q);
 #ifdef RX_ENABLE_TSFPQ
 static int
 rxi_FreeDataBufsTSFPQ(struct rx_packet *p, afs_uint32 first, int flush_global);
+#else
+static int rxi_FreeDataBufsToQueue(struct rx_packet *p,
+                                  afs_uint32 first,
+                                  struct rx_queue * q);
 #endif
 
 /* some rules about packets:
@@ -121,7 +122,7 @@ rxi_FreeDataBufsTSFPQ(struct rx_packet *p, afs_uint32 first, int flush_global);
 */
 
 /* Preconditions:
- *        all packet buffers (iov_base) are integral multiples of 
+ *        all packet buffers (iov_base) are integral multiples of
  *       the word size.
  *        offset is an integral multiple of the word size.
  */
@@ -188,17 +189,17 @@ rx_SlowReadPacket(struct rx_packet * packet, unsigned int offset, int resid,
      * offset only applies to the first iovec.
      */
     r = resid;
-    while ((resid > 0) && (i < packet->niovecs)) {
-       j = MIN(resid, packet->wirevec[i].iov_len - (offset - l));
+    while ((r > 0) && (i < packet->niovecs)) {
+       j = MIN(r, packet->wirevec[i].iov_len - (offset - l));
        memcpy(out, (char *)(packet->wirevec[i].iov_base) + (offset - l), j);
-       resid -= j;
+       r -= j;
         out += j;
        l += packet->wirevec[i].iov_len;
        offset = l;
        i++;
     }
 
-    return (resid ? (r - resid) : r);
+    return (r ? (resid - r) : resid);
 }
 
 
@@ -210,11 +211,11 @@ rx_SlowReadPacket(struct rx_packet * packet, unsigned int offset, int resid,
 afs_int32
 rx_SlowWritePacket(struct rx_packet * packet, int offset, int resid, char *in)
 {
-    int i, j, l, r;
+    unsigned int i, j, l, o, r;
     char *b;
 
-    for (l = 0, i = 1; i < packet->niovecs; i++) {
-       if (l + packet->wirevec[i].iov_len > offset) {
+    for (l = 0, i = 1, o = offset; i < packet->niovecs; i++) {
+       if (l + packet->wirevec[i].iov_len > o) {
            break;
        }
        l += packet->wirevec[i].iov_len;
@@ -226,22 +227,22 @@ rx_SlowWritePacket(struct rx_packet * packet, int offset, int resid, char *in)
      * offset only applies to the first iovec.
      */
     r = resid;
-    while ((resid > 0) && (i <= RX_MAXWVECS)) {
+    while ((r > 0) && (i <= RX_MAXWVECS)) {
        if (i >= packet->niovecs)
-           if (rxi_AllocDataBuf(packet, resid, RX_PACKET_CLASS_SEND_CBUF) > 0) /* ++niovecs as a side-effect */
+           if (rxi_AllocDataBuf(packet, r, RX_PACKET_CLASS_SEND_CBUF) > 0)     /* ++niovecs as a side-effect */
                break;
 
        b = (char *)(packet->wirevec[i].iov_base) + (offset - l);
-       j = MIN(resid, packet->wirevec[i].iov_len - (offset - l));
+       j = MIN(r, packet->wirevec[i].iov_len - (offset - l));
        memcpy(b, in, j);
-       resid -= j;
+       r -= j;
         in += j;
        l += packet->wirevec[i].iov_len;
        offset = l;
        i++;
     }
 
-    return (resid ? (r - resid) : r);
+    return (r ? (resid - r) : resid);
 }
 
 int
@@ -304,7 +305,7 @@ AllocPacketBufs(int class, int num_pkts, struct rx_queue * q)
     MUTEX_ENTER(&rx_freePktQ_lock);
 
 #ifdef KERNEL
-    for (; (num_pkts > 0) && (rxi_OverQuota2(class,num_pkts)); 
+    for (; (num_pkts > 0) && (rxi_OverQuota2(class,num_pkts));
         num_pkts--, overq++);
 
     if (overq) {
@@ -344,7 +345,7 @@ AllocPacketBufs(int class, int num_pkts, struct rx_queue * q)
 #endif /* KERNEL */
 
     for (i=0, c=queue_First(&rx_freePacketQueue, rx_packet);
-        i < num_pkts; 
+        i < num_pkts;
         i++, c=queue_Next(c, rx_packet)) {
         RX_FPQ_MARK_USED(c);
     }
@@ -461,7 +462,7 @@ rxi_FreePackets(int num_pkts, struct rx_queue *q)
 #endif /* RX_ENABLE_TSFPQ */
 
 /* this one is kind of awful.
- * In rxkad, the packet has been all shortened, and everything, ready for 
+ * In rxkad, the packet has been all shortened, and everything, ready for
  * sending.  All of a sudden, we discover we need some of that space back.
  * This isn't terribly general, because it knows that the packets are only
  * rounded up to the EBS (userdata + security header).
@@ -542,7 +543,7 @@ rxi_MorePackets(int apackets)
     osi_Assert(p);
 
     PIN(p, getme);             /* XXXXX */
-    memset((char *)p, 0, getme);
+    memset(p, 0, getme);
     RX_TS_INFO_GET(rx_ts_info);
 
     RX_TS_FPQ_LOCAL_ALLOC(rx_ts_info,apackets);
@@ -596,13 +597,15 @@ rxi_MorePackets(int apackets)
     osi_Assert(p);
 
     PIN(p, getme);             /* XXXXX */
-    memset((char *)p, 0, getme);
+    memset(p, 0, getme);
     NETPRI;
     MUTEX_ENTER(&rx_freePktQ_lock);
 
     for (e = p + apackets; p < e; p++) {
         RX_PACKET_IOV_INIT(p);
+#ifdef RX_TRACK_PACKETS
        p->flags |= RX_PKTFLAG_FREE;
+#endif
        p->niovecs = 2;
 
        queue_Append(&rx_freePacketQueue, p);
@@ -613,6 +616,7 @@ rxi_MorePackets(int apackets)
        rx_mallocedP = p;
     }
 
+    rx_nPackets += apackets;
     rx_nFreePackets += apackets;
     rxi_NeedMorePackets = FALSE;
     rxi_PacketsUnWait();
@@ -635,7 +639,7 @@ rxi_MorePacketsTSFPQ(int apackets, int flush_global, int num_keep_local)
     p = (struct rx_packet *)osi_Alloc(getme);
 
     PIN(p, getme);             /* XXXXX */
-    memset((char *)p, 0, getme);
+    memset(p, 0, getme);
     RX_TS_INFO_GET(rx_ts_info);
 
     RX_TS_FPQ_LOCAL_ALLOC(rx_ts_info,apackets);
@@ -649,7 +653,7 @@ rxi_MorePacketsTSFPQ(int apackets, int flush_global, int num_keep_local)
         RX_PACKET_IOV_INIT(p);
        p->niovecs = 2;
        RX_TS_FPQ_CHECKIN(rx_ts_info,p);
-       
+
         NETPRI;
         MUTEX_ENTER(&rx_freePktQ_lock);
 #ifdef RXDEBUG_PACKET
@@ -662,7 +666,7 @@ rxi_MorePacketsTSFPQ(int apackets, int flush_global, int num_keep_local)
     }
     rx_ts_info->_FPQ.delta += apackets;
 
-    if (flush_global && 
+    if (flush_global &&
         (num_keep_local < apackets)) {
         NETPRI;
        MUTEX_ENTER(&rx_freePktQ_lock);
@@ -700,16 +704,18 @@ rxi_MorePacketsNoLock(int apackets)
             osi_Assert(apackets > 0);
         }
     } while(p == NULL);
-    memset((char *)p, 0, getme);
+    memset(p, 0, getme);
 
 #ifdef RX_ENABLE_TSFPQ
     RX_TS_INFO_GET(rx_ts_info);
     RX_TS_FPQ_GLOBAL_ALLOC(rx_ts_info,apackets);
-#endif /* RX_ENABLE_TSFPQ */ 
+#endif /* RX_ENABLE_TSFPQ */
 
     for (e = p + apackets; p < e; p++) {
         RX_PACKET_IOV_INIT(p);
+#ifdef RX_TRACK_PACKETS
        p->flags |= RX_PKTFLAG_FREE;
+#endif
        p->niovecs = 2;
 
        queue_Append(&rx_freePacketQueue, p);
@@ -721,13 +727,12 @@ rxi_MorePacketsNoLock(int apackets)
     }
 
     rx_nFreePackets += apackets;
-#ifdef RX_ENABLE_TSFPQ
-    /* TSFPQ patch also needs to keep track of total packets */
     MUTEX_ENTER(&rx_packets_mutex);
     rx_nPackets += apackets;
+#ifdef RX_ENABLE_TSFPQ
     RX_TS_FPQ_COMPUTE_LIMITS;
-    MUTEX_EXIT(&rx_packets_mutex);
 #endif /* RX_ENABLE_TSFPQ */
+    MUTEX_EXIT(&rx_packets_mutex);
     rxi_NeedMorePackets = FALSE;
     rxi_PacketsUnWait();
 }
@@ -788,7 +793,7 @@ void
 rx_CheckPackets(void)
 {
     if (rxi_NeedMorePackets) {
-       rxi_MorePackets(rx_initSendWindow);
+       rxi_MorePackets(rx_maxSendWindow);
     }
 }
 
@@ -799,9 +804,9 @@ rx_CheckPackets(void)
    In any event, we assume the former, and append the packets to the end
    of the free list.  */
 /* This explanation is bogus.  The free list doesn't remain in any kind of
-   useful order for afs_int32: the packets in use get pretty much randomly scattered 
+   useful order for afs_int32: the packets in use get pretty much randomly scattered
    across all the pages.  In order to permit unused {packets,bufs} to page out, they
-   must be stored so that packets which are adjacent in memory are adjacent in the 
+   must be stored so that packets which are adjacent in memory are adjacent in the
    free list.  An array springs rapidly to mind.
    */
 
@@ -811,7 +816,7 @@ void
 rxi_FreePacketNoLock(struct rx_packet *p)
 {
     struct rx_ts_info_t * rx_ts_info;
-    dpf(("Free %lx\n", (unsigned long)p));
+    dpf(("Free %"AFS_PTR_FMT"\n", p));
 
     RX_TS_INFO_GET(rx_ts_info);
     RX_TS_FPQ_CHECKIN(rx_ts_info,p);
@@ -823,7 +828,7 @@ rxi_FreePacketNoLock(struct rx_packet *p)
 void
 rxi_FreePacketNoLock(struct rx_packet *p)
 {
-    dpf(("Free %lx\n", (unsigned long)p));
+    dpf(("Free %"AFS_PTR_FMT"\n", p));
 
     RX_FPQ_MARK_FREE(p);
     rx_nFreePackets++;
@@ -836,7 +841,7 @@ void
 rxi_FreePacketTSFPQ(struct rx_packet *p, int flush_global)
 {
     struct rx_ts_info_t * rx_ts_info;
-    dpf(("Free %lx\n", (unsigned long)p));
+    dpf(("Free %"AFS_PTR_FMT"\n", p));
 
     RX_TS_INFO_GET(rx_ts_info);
     RX_TS_FPQ_CHECKIN(rx_ts_info,p);
@@ -856,7 +861,7 @@ rxi_FreePacketTSFPQ(struct rx_packet *p, int flush_global)
 }
 #endif /* RX_ENABLE_TSFPQ */
 
-/* 
+/*
  * free continuation buffers off a packet into a queue
  *
  * [IN] p      -- packet from which continuation buffers will be freed
@@ -964,7 +969,7 @@ rxi_FreeDataBufsTSFPQ(struct rx_packet *p, afs_uint32 first, int flush_global)
 
 int rxi_nBadIovecs = 0;
 
-/* rxi_RestoreDataBufs 
+/* rxi_RestoreDataBufs
  *
  * Restore the correct sizes to the iovecs. Called when reusing a packet
  * for reading off the wire.
@@ -972,7 +977,7 @@ int rxi_nBadIovecs = 0;
 void
 rxi_RestoreDataBufs(struct rx_packet *p)
 {
-    int i;
+    unsigned int i;
     struct iovec *iov = &p->wirevec[2];
 
     RX_PACKET_IOV_INIT(p);
@@ -1104,7 +1109,7 @@ rxi_FreePacket(struct rx_packet *p)
 }
 #endif /* RX_ENABLE_TSFPQ */
 
-/* rxi_AllocPacket sets up p->length so it reflects the number of 
+/* rxi_AllocPacket sets up p->length so it reflects the number of
  * bytes in the packet at this point, **not including** the header.
  * The header is absolutely necessary, besides, this is the way the
  * length field is usually used */
@@ -1152,7 +1157,7 @@ rxi_AllocPacketNoLock(int class)
            osi_Panic("rxi_AllocPacket error");
 #else /* KERNEL */
         if (queue_IsEmpty(&rx_freePacketQueue))
-           rxi_MorePacketsNoLock(4 * rx_initSendWindow);
+           rxi_MorePacketsNoLock(rx_maxSendWindow);
 #endif /* KERNEL */
 
 
@@ -1161,11 +1166,11 @@ rxi_AllocPacketNoLock(int class)
 
     RX_TS_FPQ_CHECKOUT(rx_ts_info,p);
 
-    dpf(("Alloc %lx, class %d\n", (unsigned long)p, class));
+    dpf(("Alloc %"AFS_PTR_FMT", class %d\n", p, class));
 
 
     /* have to do this here because rx_FlushWrite fiddles with the iovs in
-     * order to truncate outbound packets.  In the near future, may need 
+     * order to truncate outbound packets.  In the near future, may need
      * to allocate bufs from a static pool here, and/or in AllocSendPacket
      */
     RX_PACKET_IOV_FULLINIT(p);
@@ -1211,7 +1216,7 @@ rxi_AllocPacketNoLock(int class)
        osi_Panic("rxi_AllocPacket error");
 #else /* KERNEL */
     if (queue_IsEmpty(&rx_freePacketQueue))
-       rxi_MorePacketsNoLock(4 * rx_initSendWindow);
+       rxi_MorePacketsNoLock(rx_maxSendWindow);
 #endif /* KERNEL */
 
     rx_nFreePackets--;
@@ -1219,11 +1224,11 @@ rxi_AllocPacketNoLock(int class)
     queue_Remove(p);
     RX_FPQ_MARK_USED(p);
 
-    dpf(("Alloc %lx, class %d\n", (unsigned long)p, class));
+    dpf(("Alloc %"AFS_PTR_FMT", class %d\n", p, class));
 
 
     /* have to do this here because rx_FlushWrite fiddles with the iovs in
-     * order to truncate outbound packets.  In the near future, may need 
+     * order to truncate outbound packets.  In the near future, may need
      * to allocate bufs from a static pool here, and/or in AllocSendPacket
      */
     RX_PACKET_IOV_FULLINIT(p);
@@ -1246,7 +1251,7 @@ rxi_AllocPacketTSFPQ(int class, int pull_global)
         MUTEX_ENTER(&rx_freePktQ_lock);
 
         if (queue_IsEmpty(&rx_freePacketQueue))
-           rxi_MorePacketsNoLock(4 * rx_initSendWindow);
+           rxi_MorePacketsNoLock(rx_maxSendWindow);
 
        RX_TS_FPQ_GTOL(rx_ts_info);
 
@@ -1257,10 +1262,10 @@ rxi_AllocPacketTSFPQ(int class, int pull_global)
 
     RX_TS_FPQ_CHECKOUT(rx_ts_info,p);
 
-    dpf(("Alloc %lx, class %d\n", (unsigned long)p, class));
+    dpf(("Alloc %"AFS_PTR_FMT", class %d\n", p, class));
 
     /* have to do this here because rx_FlushWrite fiddles with the iovs in
-     * order to truncate outbound packets.  In the near future, may need 
+     * order to truncate outbound packets.  In the near future, may need
      * to allocate bufs from a static pool here, and/or in AllocSendPacket
      */
     RX_PACKET_IOV_FULLINIT(p);
@@ -1317,7 +1322,7 @@ rxi_AllocSendPacket(struct rx_call *call, int want)
            (void)rxi_AllocDataBuf(p, (want - p->length),
                                   RX_PACKET_CLASS_SEND_CBUF);
 
-       if ((unsigned)p->length > mud)
+       if (p->length > mud)
             p->length = mud;
 
        if (delta >= p->length) {
@@ -1343,7 +1348,7 @@ rxi_AllocSendPacket(struct rx_call *call, int want)
                (void)rxi_AllocDataBuf(p, (want - p->length),
                                       RX_PACKET_CLASS_SEND_CBUF);
 
-           if ((unsigned)p->length > mud)
+           if (p->length > mud)
                p->length = mud;
 
            if (delta >= p->length) {
@@ -1381,7 +1386,7 @@ rxi_AllocSendPacket(struct rx_call *call, int want)
 }
 
 #ifndef KERNEL
-#ifdef AFS_NT40_ENV     
+#ifdef AFS_NT40_ENV
 /* Windows does not use file descriptors. */
 #define CountFDs(amax) 0
 #else
@@ -1420,9 +1425,9 @@ rxi_ReadPacket(osi_socket socket, struct rx_packet *p, afs_uint32 * host,
               u_short * port)
 {
     struct sockaddr_in from;
-    int nbytes;
+    unsigned int nbytes;
     afs_int32 rlen;
-    afs_int32 tlen, savelen;
+    afs_uint32 tlen, savelen;
     struct msghdr msg;
     rx_computelen(p, tlen);
     rx_SetDataSize(p, tlen);   /* this is the size of the user data area */
@@ -1440,7 +1445,7 @@ rxi_ReadPacket(osi_socket socket, struct rx_packet *p, afs_uint32 * host,
     } else
        tlen = rlen;
 
-    /* Extend the last iovec for padding, it's just to make sure that the 
+    /* Extend the last iovec for padding, it's just to make sure that the
      * read doesn't return more data than we expect, and is done to get around
      * our problems caused by the lack of a length field in the rx header.
      * Use the extra buffer that follows the localdata in each packet
@@ -1448,7 +1453,7 @@ rxi_ReadPacket(osi_socket socket, struct rx_packet *p, afs_uint32 * host,
     savelen = p->wirevec[p->niovecs - 1].iov_len;
     p->wirevec[p->niovecs - 1].iov_len += RX_EXTRABUFFERSIZE;
 
-    memset((char *)&msg, 0, sizeof(msg));
+    memset(&msg, 0, sizeof(msg));
     msg.msg_name = (char *)&from;
     msg.msg_namelen = sizeof(struct sockaddr_in);
     msg.msg_iov = p->wirevec;
@@ -1458,7 +1463,7 @@ rxi_ReadPacket(osi_socket socket, struct rx_packet *p, afs_uint32 * host,
     /* restore the vec to its correct state */
     p->wirevec[p->niovecs - 1].iov_len = savelen;
 
-    p->length = (nbytes - RX_HEADER_SIZE);
+    p->length = (u_short)(nbytes - RX_HEADER_SIZE);
     if ((nbytes > tlen) || (p->length & 0x8000)) {     /* Bogus packet */
        if (nbytes < 0 && errno == EWOULDBLOCK) {
             if (rx_stats_active)
@@ -1474,7 +1479,7 @@ rxi_ReadPacket(osi_socket socket, struct rx_packet *p, afs_uint32 * host,
                 ntohs(from.sin_port), nbytes));
        }
        return 0;
-    } 
+    }
 #ifdef RXDEBUG
     else if ((rx_intentionallyDroppedOnReadPer100 > 0)
                && (random() % 100 < rx_intentionallyDroppedOnReadPer100)) {
@@ -1484,14 +1489,14 @@ rxi_ReadPacket(osi_socket socket, struct rx_packet *p, afs_uint32 * host,
        *port = from.sin_port;
 
        dpf(("Dropped %d %s: %x.%u.%u.%u.%u.%u.%u flags %d len %d",
-             p->header.serial, rx_packetTypes[p->header.type - 1], ntohl(*host), ntohs(*port), p->header.serial, 
-             p->header.epoch, p->header.cid, p->header.callNumber, p->header.seq, p->header.flags, 
+             p->header.serial, rx_packetTypes[p->header.type - 1], ntohl(*host), ntohs(*port), p->header.serial,
+             p->header.epoch, p->header.cid, p->header.callNumber, p->header.seq, p->header.flags,
              p->length));
 #ifdef RX_TRIMDATABUFS
        rxi_TrimDataBufs(p, 1);
 #endif
        return 0;
-    } 
+    }
 #endif
     else {
        /* Extract packet header. */
@@ -1505,7 +1510,7 @@ rxi_ReadPacket(osi_socket socket, struct rx_packet *p, afs_uint32 * host,
                 rx_MutexIncrement(rx_stats.packetsRead[p->header.type - 1], rx_stats_mutex);
            /*
             * Try to look up this peer structure.  If it doesn't exist,
-            * don't create a new one - 
+            * don't create a new one -
             * we don't keep count of the bytes sent/received if a peer
             * structure doesn't already exist.
             *
@@ -1529,7 +1534,7 @@ rxi_ReadPacket(osi_socket socket, struct rx_packet *p, afs_uint32 * host,
 #ifdef RX_TRIMDATABUFS
        /* Free any empty packet buffers at the end of this packet */
        rxi_TrimDataBufs(p, 1);
-#endif 
+#endif
        return 1;
     }
 }
@@ -1545,7 +1550,7 @@ rxi_ReadPacket(osi_socket socket, struct rx_packet *p, afs_uint32 * host,
  * last two pad bytes. */
 
 struct rx_packet *
-rxi_SplitJumboPacket(struct rx_packet *p, afs_int32 host, short port,
+rxi_SplitJumboPacket(struct rx_packet *p, afs_uint32 host, short port,
                     int first)
 {
     struct rx_packet *np;
@@ -1656,8 +1661,8 @@ cpytoc(mblk_t * mp, int off, int len, char *cp)
 }
 
 /* MTUXXX Supposed to skip <off> bytes and copy <len> bytes,
- * but it doesn't really.  
- * This sucks, anyway, do it like m_cpy.... below 
+ * but it doesn't really.
+ * This sucks, anyway, do it like m_cpy.... below
  */
 static int
 cpytoiovec(mblk_t * mp, int off, int len, struct iovec *iovs,
@@ -1776,7 +1781,7 @@ rx_mb_to_packet(amb, free, hdr_len, data_len, phandle)
 
 struct rx_packet *
 rxi_ReceiveDebugPacket(struct rx_packet *ap, osi_socket asocket,
-                      afs_int32 ahost, short aport, int istack)
+                      afs_uint32 ahost, short aport, int istack)
 {
     struct rx_debugIn tin;
     afs_int32 tl;
@@ -1794,7 +1799,7 @@ rxi_ReceiveDebugPacket(struct rx_packet *ap, osi_socket asocket,
     }
 
     rx_packetread(ap, 0, sizeof(struct rx_debugIn), (char *)&tin);
-    /* all done with packet, now set length to the truth, so we can 
+    /* all done with packet, now set length to the truth, so we can
      * reuse this packet */
     rx_computelen(ap, ap->length);
 
@@ -1805,7 +1810,7 @@ rxi_ReceiveDebugPacket(struct rx_packet *ap, osi_socket asocket,
            struct rx_debugStats tstat;
 
            /* get basic stats */
-           memset((char *)&tstat, 0, sizeof(tstat));   /* make sure spares are zero */
+           memset(&tstat, 0, sizeof(tstat));   /* make sure spares are zero */
            tstat.version = RX_DEBUGI_VERSION;
 #ifndef        RX_ENABLE_LOCKS
            tstat.waitingForPackets = rx_waitingForPackets;
@@ -1838,7 +1843,7 @@ rxi_ReceiveDebugPacket(struct rx_packet *ap, osi_socket asocket,
 
     case RX_DEBUGI_GETALLCONN:
     case RX_DEBUGI_GETCONN:{
-           int i, j;
+            unsigned int i, j;
            struct rx_connection *tc;
            struct rx_call *tcall;
            struct rx_debugConn tconn;
@@ -1851,7 +1856,7 @@ rxi_ReceiveDebugPacket(struct rx_packet *ap, osi_socket asocket,
            if (tl > 0)
                return ap;
 
-           memset((char *)&tconn, 0, sizeof(tconn));   /* make sure spares are zero */
+           memset(&tconn, 0, sizeof(tconn));   /* make sure spares are zero */
            /* get N'th (maybe) "interesting" connection info */
            for (i = 0; i < rx_hashTableSize; i++) {
 #if !defined(KERNEL)
@@ -1865,7 +1870,7 @@ rxi_ReceiveDebugPacket(struct rx_packet *ap, osi_socket asocket,
 #endif
 #endif
                MUTEX_ENTER(&rx_connHashTable_lock);
-               /* We might be slightly out of step since we are not 
+               /* We might be slightly out of step since we are not
                 * locking each call, but this is only debugging output.
                 */
                for (tc = rx_connHashTable[i]; tc; tc = tc->next) {
@@ -1947,7 +1952,7 @@ rxi_ReceiveDebugPacket(struct rx_packet *ap, osi_socket asocket,
         */
 
     case RX_DEBUGI_GETPEER:{
-           int i;
+           unsigned int i;
            struct rx_peer *tp;
            struct rx_debugPeer tpeer;
 
@@ -1958,7 +1963,7 @@ rxi_ReceiveDebugPacket(struct rx_packet *ap, osi_socket asocket,
            if (tl > 0)
                return ap;
 
-           memset((char *)&tpeer, 0, sizeof(tpeer));
+           memset(&tpeer, 0, sizeof(tpeer));
            for (i = 0; i < rx_hashTableSize; i++) {
 #if !defined(KERNEL)
                /* the time complexity of the algorithm used here
@@ -1979,6 +1984,10 @@ rxi_ReceiveDebugPacket(struct rx_packet *ap, osi_socket asocket,
                MUTEX_ENTER(&rx_peerHashTable_lock);
                for (tp = rx_peerHashTable[i]; tp; tp = tp->next) {
                    if (tin.index-- <= 0) {
+                        tp->refCount++;
+                        MUTEX_EXIT(&rx_peerHashTable_lock);
+
+                        MUTEX_ENTER(&tp->peer_lock);
                        tpeer.host = tp->host;
                        tpeer.port = tp->port;
                        tpeer.ifMTU = htons(tp->ifMTU);
@@ -2011,8 +2020,12 @@ rxi_ReceiveDebugPacket(struct rx_packet *ap, osi_socket asocket,
                            htonl(tp->bytesReceived.high);
                        tpeer.bytesReceived.low =
                            htonl(tp->bytesReceived.low);
+                        MUTEX_EXIT(&tp->peer_lock);
 
+                        MUTEX_ENTER(&rx_peerHashTable_lock);
+                        tp->refCount--;
                        MUTEX_EXIT(&rx_peerHashTable_lock);
+
                        rx_packetwrite(ap, 0, sizeof(struct rx_debugPeer),
                                       (char *)&tpeer);
                        tl = ap->length;
@@ -2078,7 +2091,7 @@ rxi_ReceiveDebugPacket(struct rx_packet *ap, osi_socket asocket,
 
 struct rx_packet *
 rxi_ReceiveVersionPacket(struct rx_packet *ap, osi_socket asocket,
-                        afs_int32 ahost, short aport, int istack)
+                        afs_uint32 ahost, short aport, int istack)
 {
     afs_int32 tl;
 
@@ -2107,13 +2120,11 @@ rxi_ReceiveVersionPacket(struct rx_packet *ap, osi_socket asocket,
 /* send a debug packet back to the sender */
 static void
 rxi_SendDebugPacket(struct rx_packet *apacket, osi_socket asocket,
-                   afs_int32 ahost, short aport, afs_int32 istack)
+                   afs_uint32 ahost, short aport, afs_int32 istack)
 {
     struct sockaddr_in taddr;
-    int i;
-    int nbytes;
+    unsigned int i, nbytes, savelen = 0;
     int saven = 0;
-    size_t savelen = 0;
 #ifdef KERNEL
     int waslocked = ISAFS_GLOCK();
 #endif
@@ -2210,8 +2221,18 @@ rxi_SendPacket(struct rx_call *call, struct rx_connection *conn,
      * serial number means the packet was never sent. */
     MUTEX_ENTER(&conn->conn_data_lock);
     p->header.serial = ++conn->serial;
+    if (p->length > conn->peer->maxPacketSize) {
+       if ((p->header.type == RX_PACKET_TYPE_ACK) &&
+           (p->header.flags & RX_REQUEST_ACK)) {
+           conn->lastPingSize = p->length;
+           conn->lastPingSizeSer = p->header.serial;
+       } else if (p->header.seq != 0) {
+           conn->lastPacketSize = p->length;
+           conn->lastPacketSizeSeq = p->header.seq;
+       }
+    }
     MUTEX_EXIT(&conn->conn_data_lock);
-    /* This is so we can adjust retransmit time-outs better in the face of 
+    /* This is so we can adjust retransmit time-outs better in the face of
      * rapidly changing round-trip times.  RTO estimation is not a la Karn.
      */
     if (p->firstSerial == 0) {
@@ -2229,7 +2250,7 @@ rxi_SendPacket(struct rx_call *call, struct rx_connection *conn,
 #endif
 
     /* Get network byte order header */
-    rxi_EncodePacketHeader(p); /* XXX in the event of rexmit, etc, don't need to 
+    rxi_EncodePacketHeader(p); /* XXX in the event of rexmit, etc, don't need to
                                 * touch ALL the fields */
 
     /* Send the packet out on the same socket that related packets are being
@@ -2277,16 +2298,16 @@ rxi_SendPacket(struct rx_call *call, struct rx_connection *conn,
            clock_Addmsec(&(p->retryTime),
                          10 + (((afs_uint32) p->backoff) << 8));
            /* Some systems are nice and tell us right away that we cannot
-            * reach this recipient by returning an error code. 
+            * reach this recipient by returning an error code.
             * So, when this happens let's "down" the host NOW so
             * we don't sit around waiting for this host to timeout later.
             */
-           if (call && 
+           if (call &&
 #ifdef AFS_NT40_ENV
-               code == -1 && WSAGetLastError() == WSAEHOSTUNREACH
-#elif defined(AFS_LINUX20_ENV) && defined(KERNEL)
+               (code == -1 && WSAGetLastError() == WSAEHOSTUNREACH) || (code == -WSAEHOSTUNREACH)
+#elif defined(AFS_LINUX20_ENV)
                code == -ENETUNREACH
-#elif defined(AFS_DARWIN_ENV) && defined(KERNEL)
+#elif defined(AFS_DARWIN_ENV)
                code == EHOSTUNREACH
 #else
                0
@@ -2310,7 +2331,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 %lx resend %d.%0.3d len %d", 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, (unsigned long)p, p->retryTime.sec, p->retryTime.usec / 1000, p->length));
+    dpf(("%c %d %s: %x.%u.%u.%u.%u.%u.%u flags %d, packet %"AFS_PTR_FMT" resend %d.%.3d len %d",
+          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));
 #endif
     if (rx_stats_active)
         rx_MutexIncrement(rx_stats.packetsSent[p->header.type - 1], rx_stats_mutex);
@@ -2356,6 +2380,24 @@ rxi_SendPacketList(struct rx_call *call, struct rx_connection *conn,
     MUTEX_ENTER(&conn->conn_data_lock);
     serial = conn->serial;
     conn->serial += len;
+    for (i = 0; i < len; i++) {
+       p = list[i];
+       if (p->length > conn->peer->maxPacketSize) {
+           /* a ping *or* a sequenced packet can count */
+           if ((p->length > conn->peer->maxPacketSize)) {
+               if (((p->header.type == RX_PACKET_TYPE_ACK) &&
+                    (p->header.flags & RX_REQUEST_ACK)) &&
+                   ((i == 0) || (p->length >= conn->lastPingSize))) {
+                   conn->lastPingSize = p->length;
+                   conn->lastPingSizeSer = serial + i;
+               } else if ((p->header.seq != 0) &&
+                          ((i == 0) || (p->length >= conn->lastPacketSize))) {
+                   conn->lastPacketSize = p->length;
+                   conn->lastPacketSizeSeq = p->header.seq;
+               }
+           }
+       }
+    }
     MUTEX_EXIT(&conn->conn_data_lock);
 
 
@@ -2407,7 +2449,7 @@ rxi_SendPacketList(struct rx_call *call, struct rx_connection *conn,
        /* Pre-increment, to guarantee no zero serial number; a zero
         * serial number means the packet was never sent. */
        p->header.serial = ++serial;
-       /* This is so we can adjust retransmit time-outs better in the face of 
+       /* This is so we can adjust retransmit time-outs better in the face of
         * rapidly changing round-trip times.  RTO estimation is not a la Karn.
         */
        if (p->firstSerial == 0) {
@@ -2425,7 +2467,7 @@ rxi_SendPacketList(struct rx_call *call, struct rx_connection *conn,
 #endif
 
        /* Get network byte order header */
-       rxi_EncodePacketHeader(p);      /* XXX in the event of rexmit, etc, don't need to 
+       rxi_EncodePacketHeader(p);      /* XXX in the event of rexmit, etc, don't need to
                                         * touch ALL the fields */
     }
 
@@ -2467,16 +2509,16 @@ rxi_SendPacketList(struct rx_call *call, struct rx_connection *conn,
                              10 + (((afs_uint32) p->backoff) << 8));
            }
            /* Some systems are nice and tell us right away that we cannot
-            * reach this recipient by returning an error code. 
+            * reach this recipient by returning an error code.
             * So, when this happens let's "down" the host NOW so
             * we don't sit around waiting for this host to timeout later.
             */
-           if (call && 
+           if (call &&
 #ifdef AFS_NT40_ENV
-               code == -1 && WSAGetLastError() == WSAEHOSTUNREACH
-#elif defined(AFS_LINUX20_ENV) && defined(KERNEL)
+               (code == -1 && WSAGetLastError() == WSAEHOSTUNREACH) || (code == -WSAEHOSTUNREACH)
+#elif defined(AFS_LINUX20_ENV)
                code == -ENETUNREACH
-#elif defined(AFS_DARWIN_ENV) && defined(KERNEL)
+#elif defined(AFS_DARWIN_ENV)
                code == EHOSTUNREACH
 #else
                0
@@ -2493,7 +2535,10 @@ rxi_SendPacketList(struct rx_call *call, struct rx_connection *conn,
 
     assert(p != NULL);
 
-    dpf(("%c %d %s: %x.%u.%u.%u.%u.%u.%u flags %d, packet %lx resend %d.%0.3d len %d", 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, (unsigned long)p, p->retryTime.sec, p->retryTime.usec / 1000, p->length));
+    dpf(("%c %d %s: %x.%u.%u.%u.%u.%u.%u flags %d, packet %"AFS_PTR_FMT" resend %d.%.3d len %d",
+          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));
 
 #endif
     if (rx_stats_active)
@@ -2594,7 +2639,7 @@ rxi_EncodePacketHeader(struct rx_packet *p)
 {
     afs_uint32 *buf = (afs_uint32 *) (p->wirevec[0].iov_base); /* MTUXXX */
 
-    memset((char *)buf, 0, RX_HEADER_SIZE);
+    memset(buf, 0, RX_HEADER_SIZE);
     *buf++ = htonl(p->header.epoch);
     *buf++ = htonl(p->header.cid);
     *buf++ = htonl(p->header.callNumber);
@@ -2647,8 +2692,8 @@ rxi_PrepareSendPacket(struct rx_call *call,
                      struct rx_packet *p, int last)
 {
     struct rx_connection *conn = call->conn;
-    int i;
-    ssize_t len;               /* len must be a signed type; it can go negative */
+    unsigned int i;
+    afs_int32 len;             /* len must be a signed type; it can go negative */
 
     p->flags &= ~RX_PKTFLAG_ACKED;
     p->header.cid = (conn->cid | call->channel);
@@ -2757,8 +2802,8 @@ rxi_AdjustDgramPackets(int frags, int mtu)
     return (2 + (maxMTU / (RX_JUMBOBUFFERSIZE + RX_JUMBOHEADERSIZE)));
 }
 
-#ifdef AFS_NT40_ENV
-/* 
+#ifndef KERNEL
+/*
  * This function can be used by the Windows Cache Manager
  * to dump the list of all rx packets so that we can determine
  * where the packet leakage is.
@@ -2766,32 +2811,44 @@ rxi_AdjustDgramPackets(int frags, int mtu)
 int rx_DumpPackets(FILE *outputFile, char *cookie)
 {
 #ifdef RXDEBUG_PACKET
-    int zilch;
     struct rx_packet *p;
+#ifdef AFS_NT40_ENV
+    int zilch;
     char output[2048];
+#define RXDPRINTF sprintf
+#define RXDPRINTOUT output
+#else
+#define RXDPRINTF fprintf
+#define RXDPRINTOUT outputFile
+#endif
 
     NETPRI;
     MUTEX_ENTER(&rx_freePktQ_lock);
-    sprintf(output, "%s - Start dumping all Rx Packets - count=%u\r\n", cookie, rx_packet_id);
+    RXDPRINTF(RXDPRINTOUT, "%s - Start dumping all Rx Packets - count=%u\r\n", cookie, rx_packet_id);
+#ifdef AFS_NT40_ENV
     WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+#endif
 
     for (p = rx_mallocedP; p; p = p->allNextp) {
-        sprintf(output, "%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, 
+        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,
                 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.type, (afs_uint32)p->header.flags, (afs_uint32)p->header.userStatus,
                 (afs_uint32)p->header.securityIndex, (afs_uint32)p->header.serviceId);
+#ifdef AFS_NT40_ENV
         WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+#endif
     }
 
-    sprintf(output, "%s - End dumping all Rx Packets\r\n", cookie);
+    RXDPRINTF(RXDPRINTOUT, "%s - End dumping all Rx Packets\r\n", cookie);
+#ifdef AFS_NT40_ENV
     WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+#endif
 
     MUTEX_EXIT(&rx_freePktQ_lock);
     USERPRI;
 #endif /* RXDEBUG_PACKET */
     return 0;
 }
-#endif /* AFS_NT40_ENV */
-
+#endif