/*
* 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
#include <afs/param.h>
#endif
-RCSID
- ("$Header$");
#ifdef KERNEL
-# if defined(UKERNEL)
-# include "afs/sysincludes.h"
-# include "afsincludes.h"
-# include "rx/rx_kcommon.h"
-# include "rx/rx_clock.h"
-# include "rx/rx_queue.h"
-# include "rx/rx_packet.h"
-# else /* defined(UKERNEL) */
-# ifdef RX_KERNEL_TRACE
-# include "../rx/rx_kcommon.h"
-# endif
-# include "h/types.h"
-# ifndef AFS_LINUX20_ENV
-# include "h/systm.h"
-# endif
-# if defined(AFS_SGI_ENV) || defined(AFS_HPUX110_ENV)
-# include "afs/sysincludes.h"
-# endif
-# if defined(AFS_OBSD_ENV)
-# include "h/proc.h"
-# endif
-# include "h/socket.h"
-# if !defined(AFS_SUN5_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_HPUX110_ENV)
-# if !defined(AFS_OSF_ENV) && !defined(AFS_AIX41_ENV)
-# include "sys/mount.h" /* it gets pulled in by something later anyway */
-# endif
-# include "h/mbuf.h"
-# endif
-# include "netinet/in.h"
-# include "afs/afs_osi.h"
-# include "rx_kmutex.h"
-# include "rx/rx_clock.h"
-# include "rx/rx_queue.h"
-# ifdef AFS_SUN5_ENV
-# include <sys/sysmacros.h>
-# endif
-# include "rx/rx_packet.h"
-# endif /* defined(UKERNEL) */
-# include "rx/rx_internal.h"
-# include "rx/rx_globals.h"
+#if defined(UKERNEL)
+#include "afs/sysincludes.h"
+#include "afsincludes.h"
+#include "rx/rx_kcommon.h"
+#include "rx/rx_clock.h"
+#include "rx/rx_queue.h"
+#include "rx/rx_packet.h"
+#else /* defined(UKERNEL) */
+#ifdef RX_KERNEL_TRACE
+#include "../rx/rx_kcommon.h"
+#endif
+#include "h/types.h"
+#ifndef AFS_LINUX20_ENV
+#include "h/systm.h"
+#endif
+#if defined(AFS_SGI_ENV) || defined(AFS_HPUX110_ENV)
+#include "afs/sysincludes.h"
+#endif
+#if defined(AFS_OBSD_ENV)
+#include "h/proc.h"
+#endif
+#include "h/socket.h"
+#if !defined(AFS_SUN5_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_HPUX110_ENV)
+#if !defined(AFS_OSF_ENV) && !defined(AFS_AIX41_ENV)
+#include "sys/mount.h" /* it gets pulled in by something later anyway */
+#endif
+#include "h/mbuf.h"
+#endif
+#include "netinet/in.h"
+#include "afs/afs_osi.h"
+#include "rx_kmutex.h"
+#include "rx/rx_clock.h"
+#include "rx/rx_queue.h"
+#ifdef AFS_SUN5_ENV
+#include <sys/sysmacros.h>
+#endif
+#include "rx/rx_packet.h"
+#endif /* defined(UKERNEL) */
+#include "rx/rx_globals.h"
#else /* KERNEL */
-# include "sys/types.h"
-# include <sys/stat.h>
-# include <errno.h>
-# if defined(AFS_NT40_ENV)
-# include <winsock2.h>
-# ifndef EWOULDBLOCK
-# define EWOULDBLOCK WSAEWOULDBLOCK
-# endif
-# include "rx_user.h"
-# include "rx_xmit_nt.h"
-# include <stdlib.h>
-# else
-# include <sys/socket.h>
-# include <netinet/in.h>
-# endif
-# include "rx_clock.h"
-# include "rx_internal.h"
-# include "rx.h"
-# include "rx_queue.h"
-# ifdef AFS_SUN5_ENV
-# include <sys/sysmacros.h>
-# endif
-# include "rx_packet.h"
-# include "rx_globals.h"
-# include <lwp.h>
-# include <assert.h>
-# include <string.h>
-# ifdef HAVE_UNISTD_H
-# include <unistd.h>
-# endif
+#include "sys/types.h"
+#include <sys/stat.h>
+#include <errno.h>
+#if defined(AFS_NT40_ENV)
+#include <winsock2.h>
+#ifndef EWOULDBLOCK
+#define EWOULDBLOCK WSAEWOULDBLOCK
+#endif
+#include "rx_user.h"
+#include "rx_xmit_nt.h"
+#include <stdlib.h>
+#else
+#include <sys/socket.h>
+#include <netinet/in.h>
+#endif
+#include "rx_clock.h"
+#include "rx.h"
+#include "rx_queue.h"
+#ifdef AFS_SUN5_ENV
+#include <sys/sysmacros.h>
+#endif
+#include "rx_packet.h"
+#include "rx_globals.h"
+#include <lwp.h>
+#include <assert.h>
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
#endif /* KERNEL */
#ifdef RX_LOCKS_DB
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:
*/
/* 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.
*/
* 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);
}
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;
* 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
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) {
if (rx_stats_active) {
switch (class) {
case RX_PACKET_CLASS_RECEIVE:
- rx_AtomicIncrement(rx_stats.receivePktAllocFailures, rx_stats_mutex);
+ rx_MutexIncrement(rx_stats.receivePktAllocFailures, rx_stats_mutex);
break;
case RX_PACKET_CLASS_SEND:
- rx_AtomicIncrement(rx_stats.sendPktAllocFailures, rx_stats_mutex);
+ rx_MutexIncrement(rx_stats.sendPktAllocFailures, rx_stats_mutex);
break;
case RX_PACKET_CLASS_SPECIAL:
- rx_AtomicIncrement(rx_stats.specialPktAllocFailures, rx_stats_mutex);
+ rx_MutexIncrement(rx_stats.specialPktAllocFailures, rx_stats_mutex);
break;
case RX_PACKET_CLASS_RECV_CBUF:
- rx_AtomicIncrement(rx_stats.receiveCbufPktAllocFailures, rx_stats_mutex);
+ rx_MutexIncrement(rx_stats.receiveCbufPktAllocFailures, rx_stats_mutex);
break;
case RX_PACKET_CLASS_SEND_CBUF:
- rx_AtomicIncrement(rx_stats.sendCbufPktAllocFailures, rx_stats_mutex);
+ rx_MutexIncrement(rx_stats.sendCbufPktAllocFailures, rx_stats_mutex);
break;
}
}
#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);
}
#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).
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);
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);
rx_mallocedP = p;
}
+ rx_nPackets += apackets;
rx_nFreePackets += apackets;
rxi_NeedMorePackets = FALSE;
rxi_PacketsUnWait();
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);
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
}
rx_ts_info->_FPQ.delta += apackets;
- if (flush_global &&
+ if (flush_global &&
(num_keep_local < apackets)) {
NETPRI;
MUTEX_ENTER(&rx_freePktQ_lock);
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);
}
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();
}
rx_CheckPackets(void)
{
if (rxi_NeedMorePackets) {
- rxi_MorePackets(rx_initSendWindow);
+ rxi_MorePackets(rx_maxSendWindow);
}
}
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.
*/
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);
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++;
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);
}
#endif /* RX_ENABLE_TSFPQ */
-/*
+/*
* free continuation buffers off a packet into a queue
*
* [IN] p -- packet from which continuation buffers will be freed
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.
void
rxi_RestoreDataBufs(struct rx_packet *p)
{
- int i;
+ unsigned int i;
struct iovec *iov = &p->wirevec[2];
RX_PACKET_IOV_INIT(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 */
if (rx_stats_active) {
switch (class) {
case RX_PACKET_CLASS_RECEIVE:
- rx_AtomicIncrement(rx_stats.receivePktAllocFailures, rx_stats_mutex);
+ rx_MutexIncrement(rx_stats.receivePktAllocFailures, rx_stats_mutex);
break;
case RX_PACKET_CLASS_SEND:
- rx_AtomicIncrement(rx_stats.sendPktAllocFailures, rx_stats_mutex);
+ rx_MutexIncrement(rx_stats.sendPktAllocFailures, rx_stats_mutex);
break;
case RX_PACKET_CLASS_SPECIAL:
- rx_AtomicIncrement(rx_stats.specialPktAllocFailures, rx_stats_mutex);
+ rx_MutexIncrement(rx_stats.specialPktAllocFailures, rx_stats_mutex);
break;
case RX_PACKET_CLASS_RECV_CBUF:
- rx_AtomicIncrement(rx_stats.receiveCbufPktAllocFailures, rx_stats_mutex);
+ rx_MutexIncrement(rx_stats.receiveCbufPktAllocFailures, rx_stats_mutex);
break;
case RX_PACKET_CLASS_SEND_CBUF:
- rx_AtomicIncrement(rx_stats.sendCbufPktAllocFailures, rx_stats_mutex);
+ rx_MutexIncrement(rx_stats.sendCbufPktAllocFailures, rx_stats_mutex);
break;
}
}
#endif /* KERNEL */
if (rx_stats_active)
- rx_AtomicIncrement(rx_stats.packetRequests, rx_stats_mutex);
+ rx_MutexIncrement(rx_stats.packetRequests, rx_stats_mutex);
if (queue_IsEmpty(&rx_ts_info->_FPQ)) {
#ifdef KERNEL
osi_Panic("rxi_AllocPacket error");
#else /* KERNEL */
if (queue_IsEmpty(&rx_freePacketQueue))
- rxi_MorePacketsNoLock(4 * rx_initSendWindow);
+ rxi_MorePacketsNoLock(rx_maxSendWindow);
#endif /* KERNEL */
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);
if (rx_stats_active) {
switch (class) {
case RX_PACKET_CLASS_RECEIVE:
- rx_AtomicIncrement(rx_stats.receivePktAllocFailures, rx_stats_mutex);
+ rx_MutexIncrement(rx_stats.receivePktAllocFailures, rx_stats_mutex);
break;
case RX_PACKET_CLASS_SEND:
- rx_AtomicIncrement(rx_stats.sendPktAllocFailures, rx_stats_mutex);
+ rx_MutexIncrement(rx_stats.sendPktAllocFailures, rx_stats_mutex);
break;
case RX_PACKET_CLASS_SPECIAL:
- rx_AtomicIncrement(rx_stats.specialPktAllocFailures, rx_stats_mutex);
+ rx_MutexIncrement(rx_stats.specialPktAllocFailures, rx_stats_mutex);
break;
case RX_PACKET_CLASS_RECV_CBUF:
- rx_AtomicIncrement(rx_stats.receiveCbufPktAllocFailures, rx_stats_mutex);
+ rx_MutexIncrement(rx_stats.receiveCbufPktAllocFailures, rx_stats_mutex);
break;
case RX_PACKET_CLASS_SEND_CBUF:
- rx_AtomicIncrement(rx_stats.sendCbufPktAllocFailures, rx_stats_mutex);
+ rx_MutexIncrement(rx_stats.sendCbufPktAllocFailures, rx_stats_mutex);
break;
}
}
#endif /* KERNEL */
if (rx_stats_active)
- rx_AtomicIncrement(rx_stats.packetRequests, rx_stats_mutex);
+ rx_MutexIncrement(rx_stats.packetRequests, rx_stats_mutex);
#ifdef KERNEL
if (queue_IsEmpty(&rx_freePacketQueue))
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--;
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);
RX_TS_INFO_GET(rx_ts_info);
if (rx_stats_active)
- rx_AtomicIncrement(rx_stats.packetRequests, rx_stats_mutex);
+ rx_MutexIncrement(rx_stats.packetRequests, rx_stats_mutex);
if (pull_global && queue_IsEmpty(&rx_ts_info->_FPQ)) {
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);
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);
(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) {
(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) {
}
#ifndef KERNEL
-#ifdef AFS_NT40_ENV
+#ifdef AFS_NT40_ENV
/* Windows does not use file descriptors. */
#define CountFDs(amax) 0
#else
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 */
} 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
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;
/* 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)
- rx_AtomicIncrement(rx_stats.noPacketOnRead, rx_stats_mutex);
+ rx_MutexIncrement(rx_stats.noPacketOnRead, rx_stats_mutex);
} else if (nbytes <= 0) {
if (rx_stats_active) {
MUTEX_ENTER(&rx_stats_mutex);
- rx_AtomicIncrement_NL(rx_stats.bogusPacketOnRead);
- rx_AtomicSwap(&rx_stats.bogusHost, from.sin_addr.s_addr, rx_stats_mutex);
+ rx_stats.bogusPacketOnRead++;
+ rx_stats.bogusHost = from.sin_addr.s_addr;
MUTEX_EXIT(&rx_stats_mutex);
}
dpf(("B: bogus packet from [%x,%d] nb=%d", ntohl(from.sin_addr.s_addr),
ntohs(from.sin_port), nbytes));
}
return 0;
- }
+ }
#ifdef RXDEBUG
else if ((rx_intentionallyDroppedOnReadPer100 > 0)
&& (random() % 100 < rx_intentionallyDroppedOnReadPer100)) {
*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. */
if (p->header.type > 0 && p->header.type < RX_N_PACKET_TYPES) {
struct rx_peer *peer;
if (rx_stats_active)
- rx_AtomicIncrement(rx_stats.packetsRead[p->header.type - 1], rx_stats_mutex);
+ 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.
*
* it may have no refCount, meaning we could race with
* ReapConnections
*/
- if (peer && (rx_AtomicPeek_NL(peer->refCount) > 0)) {
+ if (peer && (peer->refCount > 0)) {
MUTEX_ENTER(&peer->peer_lock);
hadd32(peer->bytesReceived, p->length);
MUTEX_EXIT(&peer->peer_lock);
#ifdef RX_TRIMDATABUFS
/* Free any empty packet buffers at the end of this packet */
rxi_TrimDataBufs(p, 1);
-#endif
+#endif
return 1;
}
}
* 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;
}
/* 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,
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;
}
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);
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;
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;
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)
#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) {
*/
case RX_DEBUGI_GETPEER:{
- int i;
+ unsigned int i;
struct rx_peer *tp;
struct rx_debugPeer tpeer;
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
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);
tpeer.idleWhen = htonl(tp->idleWhen);
- tpeer.refCount = htons(rx_AtomicPeek_NL(tp->refCount));
+ tpeer.refCount = htons(tp->refCount);
tpeer.burstSize = tp->burstSize;
tpeer.burst = tp->burst;
tpeer.burstWait.sec = htonl(tp->burstWait.sec);
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;
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;
/* 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
* 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) {
#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
p->length + RX_HEADER_SIZE, istack)) != 0) {
/* send failed, so let's hurry up the resend, eh? */
if (rx_stats_active)
- rx_AtomicIncrement(rx_stats.netSendFailures, rx_stats_mutex);
+ rx_MutexIncrement(rx_stats.netSendFailures, rx_stats_mutex);
p->retryTime = p->timeSent; /* resend it very soon */
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
#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_AtomicIncrement(rx_stats.packetsSent[p->header.type - 1], rx_stats_mutex);
+ rx_MutexIncrement(rx_stats.packetsSent[p->header.type - 1], rx_stats_mutex);
MUTEX_ENTER(&peer->peer_lock);
hadd32(peer->bytesSent, p->length);
MUTEX_EXIT(&peer->peer_lock);
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);
/* 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) {
#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 */
}
istack)) != 0) {
/* send failed, so let's hurry up the resend, eh? */
if (rx_stats_active)
- rx_AtomicIncrement(rx_stats.netSendFailures, rx_stats_mutex);
+ rx_MutexIncrement(rx_stats.netSendFailures, rx_stats_mutex);
for (i = 0; i < len; i++) {
p = list[i];
p->retryTime = p->timeSent; /* resend it very soon */
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
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)
- rx_AtomicIncrement(rx_stats.packetsSent[p->header.type - 1], rx_stats_mutex);
+ rx_MutexIncrement(rx_stats.packetsSent[p->header.type - 1], rx_stats_mutex);
MUTEX_ENTER(&peer->peer_lock);
hadd32(peer->bytesSent, p->length);
MUTEX_EXIT(&peer->peer_lock);
{
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);
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);
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.
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