rx: Process all errors received

When we receive a buffer of errors from the error queue, loop through
all of them, and do not stop at the first applicable one we find.

Change-Id: Iad928e0489041b360fe705ac397836650b30091e
Reviewed-on: http://gerrit.openafs.org/8116
Reviewed-by: Simon Wilkinson <simonxwilkinson@gmail.com>
Reviewed-by: Derrick Brashear <shadow@your-file-system.com>
Reviewed-by: Chas Williams - CONTRACTOR <chas@cmf.nrl.navy.mil>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
This commit is contained in:
Andrew Deason 2012-09-10 16:31:01 -05:00 committed by Derrick Brashear
parent c172d469dd
commit 0ac9fe184a
2 changed files with 19 additions and 31 deletions

View File

@ -128,21 +128,21 @@ osi_HandleSocketError(osi_socket so, char *cmsgbuf, size_t cmsgbuf_len)
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg && CMSG_OK(&msg, cmsg);
cmsg = CMSG_NXTHDR(&msg, cmsg)) {
if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVERR)
break;
if (cmsg->cmsg_level != SOL_IP || cmsg->cmsg_type != IP_RECVERR) {
continue;
}
err = CMSG_DATA(cmsg);
offender = SO_EE_OFFENDER(err);
if (offender->sa_family != AF_INET) {
continue;
}
memcpy(&addr, offender, sizeof(addr));
rxi_ProcessNetError(err, addr.sin_addr.s_addr, addr.sin_port);
}
if (!cmsg)
return 0;
err = CMSG_DATA(cmsg);
offender = SO_EE_OFFENDER(err);
if (offender->sa_family != AF_INET)
return 1;
memcpy(&addr, offender, sizeof(addr));
rxi_ProcessNetError(err, addr.sin_addr.s_addr, addr.sin_port);
return 1;
}

View File

@ -780,7 +780,6 @@ rx_SetMaxMTU(int mtu)
int
rxi_HandleSocketError(int socket)
{
int ret = 0;
struct msghdr msg;
struct cmsghdr *cmsg;
struct sock_extended_err *err;
@ -798,26 +797,15 @@ rxi_HandleSocketError(int socket)
code = recvmsg(socket, &msg, MSG_ERRQUEUE|MSG_DONTWAIT|MSG_TRUNC);
if (code < 0 || !(msg.msg_flags & MSG_ERRQUEUE))
goto out;
return 0;
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
if ((char *)cmsg - controlmsgbuf > msg.msg_controllen - CMSG_SPACE(0) ||
(char *)cmsg - controlmsgbuf > msg.msg_controllen - CMSG_SPACE(cmsg->cmsg_len) ||
cmsg->cmsg_len == 0) {
cmsg = 0;
break;
if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVERR) {
err = (struct sock_extended_err *)CMSG_DATA(cmsg);
rxi_ProcessNetError(err, addr.sin_addr.s_addr, addr.sin_port);
}
if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVERR)
break;
}
if (!cmsg)
goto out;
ret = 1;
err = (struct sock_extended_err *) CMSG_DATA(cmsg);
rxi_ProcessNetError(err, addr.sin_addr.s_addr, addr.sin_port);
out:
return ret;
return 1;
}
#endif