[no subject]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Chris Friesen <cfriesen@xxxxxxxxxx>
Subject: UDP error handling inconsistencies.
Reply-To: 

	Hi,

according to the documentation (man 7 udp):

"All  fatal  errors  will  be  passed  to  the user as an error return
even when the socket is not connected. This includes asynchronous errors 
received from the network."

and experience shows that it is wrong (simply sending a packet
to a non existing port on another host). The error disappeared
for some reason in 2.3.41, which was released in January 2000 
(yeah, almost 8 years ago, I've been doing some kernel paleontology). 
I found this when upgrading a machine, which has been running 
almost nonstop since 1999. 

Not only the code for ipv4 does not match the documentation but
it seems that the ipv6 behaviour is subtly different from ipv4,
which I try to resume in the following table (which may be wrong,
as my head spins with all the negatives in the logic):

connected	recverr 	Error reported?
socket?		set ?		Doc.	IPv4	IPv6
No		No		Hard	No	No
No		Yes		Yes	Yes	Yes
Yes		No		Yes	No	Hard
Yes		Yes		Yes	Yes	Yes

A patch to restore pre-2.3.41 behaviour for IPv4 follows (and the 
logic becomes much clearer IMO, not only because it avoids a goto), 
but I'm not sure that it should be applied.

I've been running it for 24 hours without ill effects (my test program
reacts much faster when the other end is not running instead of waiting 
for a timeout in poll(2)), but I'm afraid that existing applications 
might break when confronted with a sedimented bug/feature which has 
been the behaviour against which they have been tested.

On the other hand, I feel that subtle corner cases differences
between IPv4 and IPv6 should not be allowed. I could produce a
patch for IPv6 but I don't have any IPv6 environment nor the time
to set one up for testing.

BTW, I've been trying to follow UDP's sendmsg paths and I still
have not found where the check for sk->sk_err (or the call to
sock_error() actually) is done.

I have also found at least a reference to a similar problem
on lkml by Chris Friesen:

http://www.ussg.iu.edu/hypermail/linux/kernel/0308.3/0259.html

but there are exactly zero replies to this post.

	Regards,
	Gabriel

P.S.: if inet->recverr is the unfrequent case, the first if in
the patch should become if (unlikely(inet->recverr)). I have no
idea of how frequently RECVERR option is set.


diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 2835535..bca532c 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -380,14 +380,13 @@ void __udp4_lib_err(struct sk_buff *skb, u32 info, struct hlist_head udptable[])
 	 *      RFC1122: OK.  Passes ICMP errors back to application, as per
 	 *	4.1.3.3.
 	 */
-	if (!inet->recverr) {
-		if (!harderr || sk->sk_state != TCP_ESTABLISHED)
-			goto out;
-	} else {
+	if (inet->recverr) {
 		ip_icmp_error(sk, skb, err, uh->dest, info, (u8*)(uh+1));
 	}
-	sk->sk_err = err;
-	sk->sk_error_report(sk);
+	if (harderr || sk->sk_state == TCP_ESTABLISHED) {
+			sk->sk_err = err;
+			sk->sk_error_report(sk);
+	}
 out:
 	sock_put(sk);
 }
-
To unsubscribe from this list: send the line "unsubscribe linux-net" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux