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