[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[hurd] 22/37: Backport Linux changes for proper TCP EOF handling
From: |
Samuel Thibault |
Subject: |
[hurd] 22/37: Backport Linux changes for proper TCP EOF handling |
Date: |
Mon, 09 Feb 2015 09:59:10 +0000 |
This is an automated email from the git hooks/post-receive script.
sthibault pushed a commit to annotated tag upstream/hurd/0.5.git20150208
in repository hurd.
commit 87fad50310f2bd0dcc990e80e23b09768918cf5b
Author: Samuel Thibault <address@hidden>
Date: Sat Jan 3 17:44:01 2015 +0100
Backport Linux changes for proper TCP EOF handling
Notably when remote eagerly sends a RST: we want to return EOF to the
application, not EPIPE.
* pfinet/linux-src/net/ipv4/tcp_output.c (tcp_connect): Set sk->done to 0.
* pfinet/linux-src/net/ipv4/tcp_input.c (tcp_fin): Set RCV_SHUTDOWN, and
sk->done to 1.
* pfinet/linux-src/net/ipv4/tcp.c (tcp_recv_urg): Only return ENOTCONN when
we never actually connect. Always return 0 when reception is closed.
(tcp_recvmsg): When any data is available, ignore errors and EOF. When no
data is available, first check for reception being closed, then for errors.
---
pfinet/linux-src/net/ipv4/tcp.c | 59 ++++++++++++++++------------------
pfinet/linux-src/net/ipv4/tcp_input.c | 3 ++
pfinet/linux-src/net/ipv4/tcp_output.c | 1 +
3 files changed, 31 insertions(+), 32 deletions(-)
diff --git a/pfinet/linux-src/net/ipv4/tcp.c b/pfinet/linux-src/net/ipv4/tcp.c
index 8cde385..1a05743 100644
--- a/pfinet/linux-src/net/ipv4/tcp.c
+++ b/pfinet/linux-src/net/ipv4/tcp.c
@@ -1059,13 +1059,11 @@ static int tcp_recv_urg(struct sock * sk, int nonblock,
if (sk->err)
return sock_error(sk);
- if (sk->done)
+ if (sk->state == TCP_CLOSE && !sk->done)
return -ENOTCONN;
- if (sk->state == TCP_CLOSE || (sk->shutdown & RCV_SHUTDOWN)) {
- sk->done = 1;
+ if (sk->state == TCP_CLOSE || (sk->shutdown & RCV_SHUTDOWN))
return 0;
- }
lock_sock(sk);
if (tp->urg_data & URG_VALID) {
@@ -1177,9 +1175,6 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg,
int err = 0;
int target = 1; /* Read at least this many bytes */
- if (sk->err)
- return sock_error(sk);
-
if (sk->state == TCP_LISTEN)
return -ENOTCONN;
@@ -1261,36 +1256,36 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg,
if (copied >= target)
break;
- /*
- These three lines and clause if (sk->state == TCP_CLOSE)
- are unlikely to be correct, if target > 1.
- I DO NOT FIX IT, because I have no idea, what
- POSIX prescribes to make here. Probably, it really
- wants to lose data 8), if not all target is received.
- --ANK
- */
- if (sk->err && !(flags&MSG_PEEK)) {
- copied = sock_error(sk);
- break;
- }
+ if (copied) {
+ if (sk->err ||
+ sk->state == TCP_CLOSE ||
+ (sk->shutdown & RCV_SHUTDOWN) ||
+ nonblock)
+ break;
+ } else {
+ if (sk->done)
+ break;
- if (sk->shutdown & RCV_SHUTDOWN) {
- sk->done = 1;
- break;
- }
+ if (sk->err) {
+ copied = sock_error(sk);
+ break;
+ }
+
+ if (sk->shutdown & RCV_SHUTDOWN)
+ break;
- if (sk->state == TCP_CLOSE) {
- if (!sk->done) {
- sk->done = 1;
+ if (sk->state == TCP_CLOSE) {
+ if (!sk->done) {
+ copied = -ENOTCONN;
+ break;
+ }
break;
}
- copied = -ENOTCONN;
- break;
- }
- if (nonblock) {
- copied = -EAGAIN;
- break;
+ if (nonblock) {
+ copied = -EAGAIN;
+ break;
+ }
}
cleanup_rbuf(sk, copied);
diff --git a/pfinet/linux-src/net/ipv4/tcp_input.c
b/pfinet/linux-src/net/ipv4/tcp_input.c
index e84eaf4..e2dfc15 100644
--- a/pfinet/linux-src/net/ipv4/tcp_input.c
+++ b/pfinet/linux-src/net/ipv4/tcp_input.c
@@ -1129,6 +1129,9 @@ static void tcp_fin(struct sk_buff *skb, struct sock *sk,
struct tcphdr *th)
tcp_send_ack(sk);
+ sk->shutdown |= RCV_SHUTDOWN;
+ sk->done = 1;
+
if (!sk->dead) {
sk->state_change(sk);
sock_wake_async(sk->socket, 1);
diff --git a/pfinet/linux-src/net/ipv4/tcp_output.c
b/pfinet/linux-src/net/ipv4/tcp_output.c
index 9ea4b7a..a15b7b3 100644
--- a/pfinet/linux-src/net/ipv4/tcp_output.c
+++ b/pfinet/linux-src/net/ipv4/tcp_output.c
@@ -922,6 +922,7 @@ void tcp_connect(struct sock *sk, struct sk_buff *buff, int
mtu)
tp->rcv_nxt = 0;
sk->err = 0;
+ sk->done = 0;
/* We'll fix this up when we get a response from the other end.
* See tcp_input.c:tcp_rcv_state_process case TCP_SYN_SENT.
--
Alioth's /usr/local/bin/git-commit-notice on
/srv/git.debian.org/git/pkg-hurd/hurd.git
- [hurd] 01/37: Makeconf: handle the task_notify protocol, (continued)
- [hurd] 01/37: Makeconf: handle the task_notify protocol, Samuel Thibault, 2015/02/09
- [hurd] 02/37: proc: register for new task notifications, Samuel Thibault, 2015/02/09
- [hurd] 07/37: ext2fs: tune the size of the inode cache, Samuel Thibault, 2015/02/09
- [hurd] 26/37: libports: silence pointless error message, Samuel Thibault, 2015/02/09
- [hurd] 12/37: Avoid ./ components in mtab output, Samuel Thibault, 2015/02/09
- [hurd] 10/37: Fix inclusion loop between hurd_types.defs and hurd/signal.h>, Samuel Thibault, 2015/02/09
- [hurd] 35/37: Explicit the keymap compatibility flags, Samuel Thibault, 2015/02/09
- [hurd] 03/37: proc: implement `proc_make_task_namespace', Samuel Thibault, 2015/02/09
- [hurd] 28/37: auth: simplify expression, Samuel Thibault, 2015/02/09
- [hurd] 29/37: auth: remove implicit assumption about the bootstrap process, Samuel Thibault, 2015/02/09
- [hurd] 22/37: Backport Linux changes for proper TCP EOF handling,
Samuel Thibault <=
- [hurd] 05/37: libpager: remove the `seqno' parameters, Samuel Thibault, 2015/02/09
- [hurd] 06/37: libpager: use libports notification functions, Samuel Thibault, 2015/02/09
- [hurd] 09/37: Replace `bcopy' with `memcpy' or `memmove' as appropriate, Samuel Thibault, 2015/02/09
- [hurd] 31/37: console: fix error and notification port handling, Samuel Thibault, 2015/02/09
- [hurd] 08/37: Replace `bzero' with `memset', Samuel Thibault, 2015/02/09
- [hurd] 04/37: hurd: add `proc_make_task_namespace', Samuel Thibault, 2015/02/09