/* rx_user.c contains routines specific to the user space UNIX implementation of rx */
+/* rxi_syscall is currently not prototyped */
+
#include <afsconfig.h>
#include <afs/param.h>
-RCSID
- ("$Header$");
# include <sys/types.h>
# include <errno.h>
# include <sys/time.h>
# include <net/if.h>
# include <sys/ioctl.h>
+# include <unistd.h>
#endif
# include <fcntl.h>
#if !defined(AFS_AIX_ENV) && !defined(AFS_NT40_ENV)
#define IPPORT_USERRESERVED 5000
# endif
+#if defined(HAVE_LINUX_ERRQUEUE_H) && defined(ADAPT_PMTU)
+#include <linux/types.h>
+#include <linux/errqueue.h>
+#ifndef IP_MTU
+#define IP_MTU 14
+#endif
+#endif
+
#ifndef AFS_NT40_ENV
# include <sys/time.h>
#endif
* Inited
*/
-pthread_mutex_t rx_if_init_mutex;
-#define LOCK_IF_INIT assert(pthread_mutex_lock(&rx_if_init_mutex)==0)
-#define UNLOCK_IF_INIT assert(pthread_mutex_unlock(&rx_if_init_mutex)==0)
+afs_kmutex_t rx_if_init_mutex;
+#define LOCK_IF_INIT MUTEX_ENTER(&rx_if_init_mutex)
+#define UNLOCK_IF_INIT MUTEX_EXIT(&rx_if_init_mutex)
/*
* The rx_if_mutex mutex protects the following global variables:
* myNetMasks
*/
-pthread_mutex_t rx_if_mutex;
-#define LOCK_IF assert(pthread_mutex_lock(&rx_if_mutex)==0)
-#define UNLOCK_IF assert(pthread_mutex_unlock(&rx_if_mutex)==0)
+afs_kmutex_t rx_if_mutex;
+#define LOCK_IF MUTEX_ENTER(&rx_if_mutex)
+#define UNLOCK_IF MUTEX_EXIT(&rx_if_mutex)
#else
#define LOCK_IF_INIT
#define UNLOCK_IF_INIT
int pmtu=IP_PMTUDISC_DONT;
#endif
#endif
-#if defined(HAVE_LINUX_ERRQUEUE_H) && defined(ADAPT_PMTU)
-#include <linux/types.h>
-#include <linux/errqueue.h>
-#ifndef IP_MTU
-#define IP_MTU 14
-#endif
-#endif
#if !defined(AFS_NT40_ENV)
if (ntohs(port) >= IPPORT_RESERVED && ntohs(port) < IPPORT_USERRESERVED) {
goto error;
}
+#ifdef AFS_NT40_ENV
+ rxi_xmit_init(socketFd);
+#endif /* AFS_NT40_ENV */
+
taddr.sin_addr.s_addr = ahost;
taddr.sin_family = AF_INET;
taddr.sin_port = (u_short) port;
len1 = 32766;
len2 = rx_UdpBufSize;
- greedy =
- (setsockopt
- (socketFd, SOL_SOCKET, SO_RCVBUF, (char *)&len2,
- sizeof(len2)) >= 0);
- if (!greedy) {
- len2 = 32766; /* fall back to old size... uh-oh! */
- }
- greedy =
+ /* find the size closest to rx_UdpBufSize that will be accepted */
+ while (!greedy && len2 > len1) {
+ greedy =
+ (setsockopt
+ (socketFd, SOL_SOCKET, SO_RCVBUF, (char *)&len2,
+ sizeof(len2)) >= 0);
+ if (!greedy)
+ len2 /= 2;
+ }
+
+ /* but do not let it get smaller than 32K */
+ if (len2 < len1)
+ len2 = len1;
+
+ if (len1 < len2)
+ len1 = len2;
+
+
+ greedy =
(setsockopt
(socketFd, SOL_SOCKET, SO_SNDBUF, (char *)&len1,
sizeof(len1)) >= 0)
if (!greedy)
(osi_Msg "%s*WARNING* Unable to increase buffering on socket\n",
name);
- MUTEX_ENTER(&rx_stats_mutex);
- rx_stats.socketGreedy = greedy;
- MUTEX_EXIT(&rx_stats_mutex);
+ if (rx_stats_active) {
+ MUTEX_ENTER(&rx_stats_mutex);
+ rx_stats.socketGreedy = greedy;
+ MUTEX_EXIT(&rx_stats_mutex);
+ }
}
#ifdef AFS_LINUX22_ENV
}
void
-osi_Panic(msg, a1, a2, a3)
- char *msg;
+osi_Panic(char *msg, ...)
{
+ va_list ap;
+ va_start(ap, msg);
(osi_Msg "Fatal Rx error: ");
- (osi_Msg msg, a1, a2, a3);
+ (osi_VMsg msg, ap);
+ va_end(ap);
fflush(stderr);
fflush(stdout);
afs_abort();
** maxSize - max number of interfaces to return.
*/
int
-rx_getAllAddr(afs_int32 * buffer, int maxSize)
+rx_getAllAddr(afs_uint32 * buffer, int maxSize)
{
int count = 0, offset = 0;
/* The IP address list can change so we must query for it */
rx_GetIFInfo();
-#ifndef AFS_NT40_ENV
- /* we don't want to use the loopback adapter which is first */
- /* this is a bad bad hack.
- * and doesn't hold true on Windows.
- */
- if ( rxi_numNetAddrs > 1 )
- offset = 1;
-#endif /* AFS_NT40_ENV */
-
for (count = 0; offset < rxi_numNetAddrs && maxSize > 0;
count++, offset++, maxSize--)
buffer[count] = htonl(rxi_NetAddrs[offset]);
return count;
}
+
+/* this function returns the total number of interface addresses
+ * the buffer has to be passed in by the caller. It also returns
+ * the matching interface mask and mtu. All values are returned
+ * in network byte order.
+ */
+int
+rx_getAllAddrMaskMtu(afs_uint32 addrBuffer[], afs_uint32 maskBuffer[],
+ afs_uint32 mtuBuffer[], int maxSize)
+{
+ int count = 0, offset = 0;
+
+ /* The IP address list can change so we must query for it */
+ rx_GetIFInfo();
+
+ for (count = 0;
+ offset < rxi_numNetAddrs && maxSize > 0;
+ count++, offset++, maxSize--) {
+ addrBuffer[count] = htonl(rxi_NetAddrs[offset]);
+ maskBuffer[count] = htonl(myNetMasks[offset]);
+ mtuBuffer[count] = htonl(myNetMTUs[offset]);
+ }
+ return count;
+}
#endif
#ifdef AFS_NT40_ENV
maxsize =
rxi_nRecvFrags * rxsize + (rxi_nRecvFrags - 1) * UDP_HDR_SIZE;
maxsize = rxi_AdjustMaxMTU(rxsize, maxsize);
- if (rx_maxReceiveSize < maxsize) {
+ if (rx_maxReceiveSize > maxsize) {
rx_maxReceiveSize = MIN(RX_MAX_PACKET_SIZE, maxsize);
rx_maxReceiveSize =
MIN(rx_maxReceiveSize, rx_maxReceiveSizeUser);
}
-
+ if (rx_MyMaxSendSize > maxsize) {
+ rx_MyMaxSendSize = MIN(RX_MAX_PACKET_SIZE, maxsize);
+ }
}
UNLOCK_IF;
#if !defined(AFS_AIX_ENV) && !defined(AFS_NT40_ENV) && !defined(AFS_LINUX20_ENV)
int
-rxi_syscall(a3, a4, a5)
- afs_uint32 a3, a4;
- void *a5;
+rxi_syscall(afs_uint32 a3, afs_uint32 a4, void *a5)
{
afs_uint32 rcode;
- void (*old) ();
+ void (*old) (int);
- old = (void (*)())signal(SIGSYS, SIG_IGN);
+ old = signal(SIGSYS, SIG_IGN);
#if defined(AFS_SGI_ENV)
- rcode = afs_syscall(a3, a4, a5);
+ rcode = afs_syscall(AFS_SYSCALL, 28, a3, a4, a5);
#else
rcode = syscall(AFS_SYSCALL, 28 /* AFSCALL_CALL */ , a3, a4, a5);
#endif /* AFS_SGI_ENV */
if (a->sin_family != AF_INET)
continue;
rxi_NetAddrs[rxi_numNetAddrs] = ntohl(a->sin_addr.s_addr);
- if (rxi_NetAddrs[rxi_numNetAddrs] == 0x7f000001) {
+ if (rx_IsLoopbackAddr(rxi_NetAddrs[rxi_numNetAddrs])) {
/* we don't really care about "localhost" */
continue;
}
#endif
}
- if (rxi_NetAddrs[rxi_numNetAddrs] != 0x7f000001) { /* ignore lo0 */
+ if (!rx_IsLoopbackAddr(rxi_NetAddrs[rxi_numNetAddrs])) { /* ignore lo0 */
int maxsize;
maxsize =
rxi_nRecvFrags * (myNetMTUs[rxi_numNetAddrs] - RX_IP_SIZE);
struct sockaddr_in addr;
#endif
+
+
LOCK_IF_INIT;
if (!Inited) {
UNLOCK_IF_INIT;
/* try to second-guess IP, and identify which link is most likely to
* be used for traffic to/from this host. */
ppaddr = ntohl(pp->host);
-
+
pp->ifMTU = 0;
pp->timeout.sec = 2;
- pp->rateFlag = 2; /* start timing after two full packets */
+ pp->rateFlag = 2; /* start timing after two full packets */
/* I don't initialize these, because I presume they are bzero'd...
* pp->burstSize pp->burst pp->burstWait.sec pp->burstWait.usec
* pp->timeout.usec */
-
+
LOCK_IF;
for (ix = 0; ix < rxi_numNetAddrs; ++ix) {
if ((rxi_NetAddrs[ix] & myNetMasks[ix]) == (ppaddr & myNetMasks[ix])) {
}
}
UNLOCK_IF;
- if (!pp->ifMTU) { /* not local */
+ if (!pp->ifMTU) { /* not local */
pp->timeout.sec = 3;
pp->ifMTU = MIN(rx_MyMaxSendSize, RX_REMOTE_PACKET_SIZE);
}
rx_MyMaxSendSize = rx_maxReceiveSizeUser = rx_maxReceiveSize = mtu;
}
-#if defined(HAVE_LINUX_ERRQUEUE_H) && defined(ADAPT_PMTU)
+#if defined(ADAPT_PMTU)
int
rxi_HandleSocketError(int socket)
{
+ int ret=0;
+#if defined(HAVE_LINUX_ERRQUEUE_H)
struct msghdr msg;
struct cmsghdr *cmsg;
struct sock_extended_err *err;
struct sockaddr_in addr;
struct sockaddr *offender;
char controlmsgbuf[256];
- int ret=0;
int code;
msg.msg_name = &addr;
err =(struct sock_extended_err *) CMSG_DATA(cmsg);
if (err->ee_errno == EMSGSIZE && err->ee_info >= 68) {
- rxi_SetPeerMtu(addr.sin_addr.s_addr, addr.sin_port,
+ rxi_SetPeerMtu(NULL, addr.sin_addr.s_addr, addr.sin_port,
err->ee_info - RX_IPUDP_SIZE);
}
/* other DEST_UNREACH's and TIME_EXCEEDED should be dealt with too */
out:
+#endif
return ret;
}
#endif