summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDamian Lukowski <damian@tvk.rwth-aachen.de>2010-02-10 18:04:08 -0800
committerDavid S. Miller <davem@davemloft.net>2010-02-10 18:04:08 -0800
commit598856407d4e20ebb4de01a91a93d89325924d43 (patch)
tree88df32f1dfad558dc652c6488032fb9c19f03958 /net
parent044c18c9f51a2b92b310e28bb121e55451b088dd (diff)
downloadlinux-stable-598856407d4e20ebb4de01a91a93d89325924d43.tar.gz
linux-stable-598856407d4e20ebb4de01a91a93d89325924d43.tar.bz2
linux-stable-598856407d4e20ebb4de01a91a93d89325924d43.zip
tcp: fix ICMP-RTO war
Make sure, that TCP has a nonzero RTT estimation after three-way handshake. Currently, a listening TCP has a value of 0 for srtt, rttvar and rto right after the three-way handshake is completed with TCP timestamps disabled. This will lead to corrupt RTO recalculation and retransmission flood when RTO is recalculated on backoff reversion as introduced in "Revert RTO on ICMP destination unreachable" (f1ecd5d9e7366609d640ff4040304ea197fbc618). This behaviour can be provoked by connecting to a server which "responds first" (like SMTP) and rejecting every packet after the handshake with dest-unreachable, which will lead to softirq load on the server (up to 30% per socket in some tests). Thanks to Ilpo Jarvinen for providing debug patches and to Denys Fedoryshchenko for reporting and testing. Changes since v3: Removed bad characters in patchfile. Reported-by: Denys Fedoryshchenko <denys@visp.net.lb> Signed-off-by: Damian Lukowski <damian@tvk.rwth-aachen.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/tcp_input.c6
1 files changed, 2 insertions, 4 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 28e029632493..3fddc69ccccc 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -5783,11 +5783,9 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
/* tcp_ack considers this ACK as duplicate
* and does not calculate rtt.
- * Fix it at least with timestamps.
+ * Force it here.
*/
- if (tp->rx_opt.saw_tstamp &&
- tp->rx_opt.rcv_tsecr && !tp->srtt)
- tcp_ack_saw_tstamp(sk, 0);
+ tcp_ack_update_rtt(sk, 0, 0);
if (tp->rx_opt.tstamp_ok)
tp->advmss -= TCPOLEN_TSTAMP_ALIGNED;