如何在linux tcp内核中检查重传定时器是否正在运行?
问问题
4360 次
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 回答