Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a3374c42 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller
Browse files

tcp: fix FIONREAD/SIOCINQ



tcp_ioctl() tries to take into account if tcp socket received a FIN
to report correct number bytes in receive queue.

But its flaky because if the application ate the last skb,
we return 1 instead of 0.

Correct way to detect that FIN was received is to test SOCK_DONE.

Reported-by: default avatarElliot Hughes <enh@google.com>
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Cc: Neal Cardwell <ncardwell@google.com>
Cc: Tom Herbert <therbert@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c6846ee1
Loading
Loading
Loading
Loading
+3 −5
Original line number Diff line number Diff line
@@ -549,14 +549,12 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
			 !tp->urg_data ||
			 before(tp->urg_seq, tp->copied_seq) ||
			 !before(tp->urg_seq, tp->rcv_nxt)) {
			struct sk_buff *skb;

			answ = tp->rcv_nxt - tp->copied_seq;

			/* Subtract 1, if FIN is in queue. */
			skb = skb_peek_tail(&sk->sk_receive_queue);
			if (answ && skb)
				answ -= tcp_hdr(skb)->fin;
			/* Subtract 1, if FIN was received */
			if (answ && sock_flag(sk, SOCK_DONE))
				answ--;
		} else
			answ = tp->urg_seq - tp->copied_seq;
		release_sock(sk);