lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <1333651563-3279-1-git-send-email-subramanian.vijay@gmail.com>
Date:	Thu,  5 Apr 2012 11:46:03 -0700
From:	Vijay Subramanian <subramanian.vijay@...il.com>
To:	netdev@...r.kernel.org
Cc:	davem@...emloft.net, ncardwell@...gle.com,
	ilpo.jarvinen@...sink.fi,
	Vijay Subramanian <subramanian.vijay@...il.com>
Subject: [PATCH net-next] tcp: Fix bug when gap in rcv sequence is filled

As per RFC2581 and the newer RFC5681, "the receiver SHOULD send an immediate ACK
when it receives a data segment that fills in all or part of a gap in the
sequence space." When TCP receiver gets the next in-sequence packet, we move
data from ofo queue to receive queue. At this point, we should send an immediate
ack by entering quickack mode.  In the current code, instead of entering
quickack mode upon requeing packets from ofo queue to receive_queue, we enter
quickack mode only when ofo queue becomes empty after requeuing.  This ignores
the possibility that there may be further packets left in ofo queue. This patch
fixes this behavior and enters quickack mode whenever packets are moved from ofo
queue to receive queue.

Also, comment has been updated to reflect that RFC5681 obsoletes RFC2581.

Signed-off-by: Vijay Subramanian <subramanian.vijay@...il.com>
---
 net/ipv4/tcp_input.c |   13 ++++++++-----
 1 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index e886e2f..ebed78d 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4388,12 +4388,14 @@ static void tcp_sack_remove(struct tcp_sock *tp)
 
 /* This one checks to see if we can put data from the
  * out_of_order queue into the receive_queue.
+ * Return 1 if data is moved from ofo queue to receive_queue and 0 otherwise.
  */
-static void tcp_ofo_queue(struct sock *sk)
+static int tcp_ofo_queue(struct sock *sk)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 	__u32 dsack_high = tp->rcv_nxt;
 	struct sk_buff *skb;
+	bool requeued = false; /*true if an skb is requeued to receive_queue*/
 
 	while ((skb = skb_peek(&tp->out_of_order_queue)) != NULL) {
 		if (after(TCP_SKB_CB(skb)->seq, tp->rcv_nxt))
@@ -4418,10 +4420,12 @@ static void tcp_ofo_queue(struct sock *sk)
 
 		__skb_unlink(skb, &tp->out_of_order_queue);
 		__skb_queue_tail(&sk->sk_receive_queue, skb);
+		requeued = true;
 		tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
 		if (tcp_hdr(skb)->fin)
 			tcp_fin(sk);
 	}
+	return requeued ? 1 : 0 ;
 }
 
 static int tcp_prune_ofo_queue(struct sock *sk);
@@ -4636,12 +4640,11 @@ queue_and_out:
 			tcp_fin(sk);
 
 		if (!skb_queue_empty(&tp->out_of_order_queue)) {
-			tcp_ofo_queue(sk);
 
-			/* RFC2581. 4.2. SHOULD send immediate ACK, when
-			 * gap in queue is filled.
+			/* RFC5681 (which obsoletes RFC2581.) 4.2. SHOULD send
+			 * immediate ACK, when gap in queue is filled.
 			 */
-			if (skb_queue_empty(&tp->out_of_order_queue))
+			if (tcp_ofo_queue(sk))
 				inet_csk(sk)->icsk_ack.pingpong = 0;
 		}
 
-- 
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ