linux内核中的TCP重传定时器

时间:2013-02-08 15:52:42

标签: linux tcp timer

如何在linux tcp内核中检查重传定时器是否正在运行?

3 个答案:

答案 0 :(得分:3)

您可以设置两个主机:发件人和收件人。在两者之间建立连接并发送一些流量,比如传输一个大文件。嗅到双方的交通。

在发送流量时设置防火墙规则以删除一些数据包,here's一个随机丢弃x%的示例:

# for randomly dropping 10% of incoming packets:
iptables -A INPUT -m statistic --mode random \ 
         --probability  0.1 -j DROP

清理:

# for the incoming packets:
iptables -D INPUT -m statistic --mode random \
         --probability 0.1 -j DROP

如果您查看捕获,您应该看到发件人多次发送数据包以克服丢弃的数据包。这表明重传正在发挥作用。

如果你将掉落率提高到100%,你会看到仅因超时而导致的重传。

答案 1 :(得分:1)

它必然会运行,否则它不是TCP的实现。请参阅RFC。

可以想象,到现在为止有人注意到系统的一部分不起作用。

关于调整它 - 请参阅/proc/sys/net/ipv4

下的配置参数

答案 2 :(得分:1)

我解决了问题,我想我应该分享解决方案。简而言之,当接收到ACK时,通过调用inet_csk_clear_xmit_timer来关闭重传定时器。 icsk_pending是inet_connection_sock结构中的标志。当接收到最早未完成数据的ACK并且因此关闭重传定时器时,不设置该标志。来自linux 3.7内核

static inline void inet_csk_clear_xmit_timer(struct sock *sk, const int what)
 {
         struct inet_connection_sock *icsk = inet_csk(sk);

         **if (what == ICSK_TIME_RETRANS || what == ICSK_TIME_PROBE0) {
                 icsk->icsk_pending = 0;**
 #ifdef INET_CSK_CLEAR_TIMERS
                 sk_stop_timer(sk, &icsk->icsk_retransmit_timer);
 #endif
         } else if (what == ICSK_TIME_DACK) {
                 icsk->icsk_ack.blocked = icsk->icsk_ack.pending = 0;
 #ifdef INET_CSK_CLEAR_TIMERS
                 sk_stop_timer(sk, &icsk->icsk_delack_timer);
 #endif
         }
 #ifdef INET_CSK_DEBUG
         else {
                 pr_debug("%s", inet_csk_timer_bug_msg);
         }
 #endif
 }