From d55df0ac8351b1518d2c3cde6e3938b98b3f21f7 Mon Sep 17 00:00:00 2001 From: Andrew Deason Date: Wed, 1 Aug 2012 15:56:27 -0400 Subject: [PATCH] LINUX: Avoid SO_ERROR for RXERRQ_ENV SO_ERROR is for receiving errors from some nonblocking operations; it has little relevance to our network operations. For Linux, use a similar structure as userspace error detection, instead of SO_ERROR. Change-Id: I2188b1a023592d44bec62f6d07666dc19732222c Reviewed-on: http://gerrit.openafs.org/7926 Tested-by: BuildBot Reviewed-by: Derrick Brashear --- src/rx/LINUX/rx_knet.c | 51 +++++++++++++++++------------------------- 1 file changed, 20 insertions(+), 31 deletions(-) diff --git a/src/rx/LINUX/rx_knet.c b/src/rx/LINUX/rx_knet.c index fccdbc42b..a6a9c2375 100644 --- a/src/rx/LINUX/rx_knet.c +++ b/src/rx/LINUX/rx_knet.c @@ -98,20 +98,21 @@ rxk_FreeSocket(struct socket *asocket) } #ifdef AFS_RXERRQ_ENV -void -handle_socket_error(osi_socket so) +int +osi_HandleSocketError(osi_socket so) { + int ret = 0; struct msghdr msg; struct cmsghdr *cmsg; struct sock_extended_err *err; struct sockaddr_in addr; struct sockaddr *offender; - char *controlmsgbuf; + char *controlmsgbuf = NULL; int code; struct socket *sop = (struct socket *)so; - if (!(controlmsgbuf=rxi_Alloc(256))) - return; + if (!(controlmsgbuf = rxi_Alloc(256))) + goto out; msg.msg_name = &addr; msg.msg_namelen = sizeof(addr); msg.msg_control = controlmsgbuf; @@ -131,6 +132,8 @@ handle_socket_error(osi_socket so) } if (!cmsg) goto out; + + ret = 1; err = CMSG_DATA(cmsg); offender = SO_EE_OFFENDER(err); @@ -149,9 +152,11 @@ handle_socket_error(osi_socket so) # endif /* other DEST_UNREACH's and TIME_EXCEEDED should be dealt with too */ -out: - rxi_Free(controlmsgbuf, 256); - return; + out: + if (controlmsgbuf) { + rxi_Free(controlmsgbuf, 256); + } + return ret; } #endif @@ -167,18 +172,10 @@ osi_NetSend(osi_socket sop, struct sockaddr_in *to, struct iovec *iovec, { struct msghdr msg; int code; + #ifdef AFS_RXERRQ_ENV - int sockerr; - int esize; - - while (1) { - sockerr=0; - esize = sizeof(sockerr); - kernel_getsockopt(sop, SOL_SOCKET, SO_ERROR, (char *)&sockerr, &esize); - if (sockerr == 0) - break; - handle_socket_error(sop); - } + while (osi_HandleSocketError(sop)) + ; #endif msg.msg_name = to; @@ -219,26 +216,18 @@ osi_NetReceive(osi_socket so, struct sockaddr_in *from, struct iovec *iov, { struct msghdr msg; int code; -#ifdef AFS_RXERRQ_ENV - int sockerr; - int esize; -#endif struct iovec tmpvec[RX_MAXWVECS + 2]; struct socket *sop = (struct socket *)so; if (iovcnt > RX_MAXWVECS + 2) { osi_Panic("Too many (%d) iovecs passed to osi_NetReceive\n", iovcnt); } + #ifdef AFS_RXERRQ_ENV - while (1) { - sockerr=0; - esize = sizeof(sockerr); - kernel_getsockopt(sop, SOL_SOCKET, SO_ERROR, (char *)&sockerr, &esize); - if (sockerr == 0) - break; - handle_socket_error(so); - } + while (osi_HandleSocketError(so)) + ; #endif + memcpy(tmpvec, iov, iovcnt * sizeof(struct iovec)); msg.msg_name = from; msg.msg_iov = tmpvec; -- 2.39.5