diff options
author | fenner <fenner@FreeBSD.org> | 1998-02-20 03:00:40 +0800 |
---|---|---|
committer | fenner <fenner@FreeBSD.org> | 1998-02-20 03:00:40 +0800 |
commit | b774a0cb957482c98977324140ea847d4a40dbcc (patch) | |
tree | 0c93d1b36e353a3cc19f5ccbf4fd9ebbfe2f56a9 /mbone | |
parent | 51953eb44f1eb0ca8b6db43a5d945186f0091319 (diff) | |
download | freebsd-ports-gnome-b774a0cb957482c98977324140ea847d4a40dbcc.tar.gz freebsd-ports-gnome-b774a0cb957482c98977324140ea847d4a40dbcc.tar.zst freebsd-ports-gnome-b774a0cb957482c98977324140ea847d4a40dbcc.zip |
Handle a bug that LBL thought was fixed in 4.4BSD but wasn't: send()
on a socket with a pending error doesn't reset the error, so the socket
is effectively useless. Use getsockopt(...SO_ERROR...) to clear the
error status. The kernel should also be patched, but this patch is
required for backwards compatibility.
Diffstat (limited to 'mbone')
-rw-r--r-- | mbone/vat/files/patch-af | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/mbone/vat/files/patch-af b/mbone/vat/files/patch-af new file mode 100644 index 000000000000..6b73cca9f5c8 --- /dev/null +++ b/mbone/vat/files/patch-af @@ -0,0 +1,117 @@ +--- net.cc.orig 1997/10/07 19:07:01 ++++ net.cc 1998/01/26 22:21:41 +@@ -163,46 +163,48 @@ + { + int cc = ::send(fd, (char*)buf, len, 0); + if (cc < 0) { +- switch (errno) { ++ /* ++ * Due to a bug in kern/uipc_socket.c, on several ++ * systems, datagram sockets incorrectly persist ++ * in an error state on receipt of any ICMP ++ * error. This causes unicast connection ++ * rendezvous problems, and worse, multicast ++ * transmission problems because several systems ++ * incorrectly send port unreachables for ++ * multicast destinations. Our work around ++ * is to call getsockopt(..., SO_ERROR, ...) ++ * which resets so->so_error. ++ * ++ * This bug originated at CSRG in Berkeley ++ * and was present in the BSD Reno networking ++ * code release. It has since been fixed ++ * in OSF-3.x. It is know to remain ++ * in 4.4BSD and AIX-4.1.3. ++ * ++ * A fix is to change the following lines from ++ * kern/uipc_socket.c: ++ * ++ * if (so_serror) ++ * snderr(so->so_error); ++ * ++ * to: ++ * ++ * if (so->so_error) { ++ * error = so->so_error; ++ * so->so_error = 0; ++ * splx(s); ++ * goto release; ++ * } ++ * ++ */ ++ int err, errlen = sizeof(err), savederrno; ++ ++ savederrno = errno; ++ getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, ++ &errlen); ++ switch (savederrno) { + case ECONNREFUSED: + /* no one listening at some site - ignore */ +-#if defined(__osf__) || defined(_AIX) +- /* +- * Due to a bug in kern/uipc_socket.c, on several +- * systems, datagram sockets incorrectly persist +- * in an error state on receipt of an ICMP +- * port-unreachable. This causes unicast connection +- * rendezvous problems, and worse, multicast +- * transmission problems because several systems +- * incorrectly send port unreachables for +- * multicast destinations. Our work around +- * is to simply close and reopen the socket +- * (by calling reset() below). +- * +- * This bug originated at CSRG in Berkeley +- * and was present in the BSD Reno networking +- * code release. It has since been fixed +- * in 4.4BSD and OSF-3.x. It is know to remain +- * in AIX-4.1.3. +- * +- * A fix is to change the following lines from +- * kern/uipc_socket.c: +- * +- * if (so_serror) +- * snderr(so->so_error); +- * +- * to: +- * +- * if (so->so_error) { +- * error = so->so_error; +- * so->so_error = 0; +- * splx(s); +- * goto release; +- * } +- * +- */ +- reset(); +-#endif + break; + + case ENETUNREACH: +@@ -217,7 +219,7 @@ + * icmp unreachable, so we should be able to + * send now. + */ +- (void)::send(ssock_, (char*)buf, len, 0); ++ (void)::send(fd, (char*)buf, len, 0); + break; + + default: +@@ -264,12 +266,14 @@ + } + int cc = ::sendmsg(ssock_, (msghdr*)&mh, 0); + if (cc < 0) { +- switch (errno) { ++ int err, errlen = sizeof(err), savederrno; ++ ++ savederrno = errno; ++ getsockopt(ssock_, SOL_SOCKET, SO_ERROR, &err, ++ &errlen); ++ switch (savederrno) { + case ECONNREFUSED: + /* no one listening at some site - ignore */ +-#if defined(__osf__) || defined(_AIX) +- reset(); +-#endif + break; + + case ENETUNREACH: |