Subject: kern/7640: (udp) socket can get stuck if ICMP is received
To: None <gnats-bugs@gnats.netbsd.org>
From: None <Havard.Eidnes@runit.sintef.no>
List: netbsd-bugs
Date: 05/24/1999 09:50:57
>Number: 7640
>Category: kern
>Synopsis: (udp) socket can get stuck if ICMP is received
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people (Kernel Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon May 24 09:50:01 1999
>Last-Modified:
>Originator: Havard Eidnes
>Organization:
RUNIT AS
>Release: NetBSD-1.3K
>Environment:
System: NetBSD vader.runit.sintef.no 1.3I NetBSD 1.3I (VADER) #0: Sat Jan 9 18:53:46 MET 1999 he@hugin.runit.sintef.no:/usr/src/sys/arch/i386/compile/VADER i386
>Description:
vat's source code contains the following comment, cut and
pasted from FreeBSD's patch-af of their port of vat:
+ /*
+ * 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;
+ * }
+ *
+ */
There is another scenario where this error will occur, and
that is if you try to use a NetBSD host as a continous traffic
source of (in my case UDP) traffic. If an ICMP Source Quench
or ICMP Port Unreachable is received, the sending socket will
get stuck not sending any more traffic and always returning
the same error over and over again.
>How-To-Repeat:
Write a program to send a continous stream of UDP datagrams to
another (local) host's port 9, while that port 9 is turned off
(causing a Port Unreachable to be returned). Watch the UDP
sender stop after the first reception of that ICMP message.
While it could be argued that's the right thing to do in
exactly this instance, completely locking up on ICMP Source
Quench reception is, umm, not very nice.
>Fix:
I'm not 100% sure of this, e.g. what effect will it have on
TCP sockets? Someone more versed in the innards of this code
should take a closer look at this fix.
--- uipc_socket.c.old Sat Jan 23 17:30:32 1999
+++ uipc_socket.c Mon May 24 18:43:00 1999
@@ -403,6 +403,9 @@
if (so->so_state & SS_CANTSENDMORE)
snderr(EPIPE);
- if (so->so_error)
- snderr(so->so_error);
+ if (so->so_error) {
+ error = so->so_error;
+ so->so_error = 0;
+ snderr(error);
+ }
if ((so->so_state & SS_ISCONNECTED) == 0) {
if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
>Audit-Trail:
>Unformatted: