1

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

4

3 回答 3

4

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

在发送流量时,设置防火墙规则以丢弃一些数据包,下面是一个随机丢弃 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%,您将看到仅由于超时而重新传输。

于 2013-02-08T16:18:13.163 回答
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
 }
于 2013-03-06T14:13:14.487 回答
1

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

可以想象,现在有人已经注意到系统的一部分不工作了。

至于调整它 - 请参阅下面的配置参数/proc/sys/net/ipv4

于 2013-02-08T17:47:17.203 回答