aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfenner <fenner@FreeBSD.org>1998-02-20 03:00:40 +0800
committerfenner <fenner@FreeBSD.org>1998-02-20 03:00:40 +0800
commitb774a0cb957482c98977324140ea847d4a40dbcc (patch)
tree0c93d1b36e353a3cc19f5ccbf4fd9ebbfe2f56a9
parent51953eb44f1eb0ca8b6db43a5d945186f0091319 (diff)
downloadfreebsd-ports-graphics-b774a0cb957482c98977324140ea847d4a40dbcc.tar.gz
freebsd-ports-graphics-b774a0cb957482c98977324140ea847d4a40dbcc.tar.zst
freebsd-ports-graphics-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.
-rw-r--r--audio/vat/files/patch-af117
-rw-r--r--mbone/vat/files/patch-af117
2 files changed, 234 insertions, 0 deletions
diff --git a/audio/vat/files/patch-af b/audio/vat/files/patch-af
new file mode 100644
index 00000000000..6b73cca9f5c
--- /dev/null
+++ b/audio/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:
diff --git a/mbone/vat/files/patch-af b/mbone/vat/files/patch-af
new file mode 100644
index 00000000000..6b73cca9f5c
--- /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: