在connect(2)[Linux 2.6.7 2004-06-23的版本]的手册页中,描述ETIMEDOUT的部分说:
ETIMEDOUT尝试连接时超时。服务器也可能 忙着接受新的联系。请注意,对于IP套接字,超时 在服务器上启用syncookies时可能会很长。
同样的评论至少也出现在Linux man-pages项目的3.35版本中。
我不了解如何在服务器上启用syncookies会导致客户端有更长的超时时间。
答案 0 :(得分:1)
我唯一的解释是,这是手册页中的一个错误,而不是作者的意思。在Linux中处理连接超时的源相对简单,可以在retransmits_timed_out()和tcp_write_timeout()函数中看到here。
基于正常指数退避定时器调用tcp_retransmit_timer()(即,就像任何其他数据包一样重新传输syn,没有特殊处理)。 tcp_retransmit_timer()调用tcp_write_timeout()(line 396),如果套接字处于SYN_SENT或SYN_RECV状态,则将变量retry_until设置为icsk_syn_retries(如果已使用setsockopt()设置)或sysctl tcp_syn_retries值。它还设置syn_set = true。这两个传递在retransmits_timed_out()上,它会检查是否有retry_until尝试发送syn。如果是,则返回true并调用tcp_write_err(),返回ETIMEDOUT错误(line 37)。在syn_set为true的情况下,retransmits_timed_out使用TCP_TIMEOUT_INIT作为其计算的基本超时,这是一个常量(定义为here)。因此,即使syncookies的存在以某种方式神奇地改变了重传计时器,它也无法改变retransmits_timed_out()计算是否有足够的时间来保证返回ETIMEDOUT。它只能改变重传次数,但是当处理setsockopt时,icsk_syn_retries只设置为here,而sysctl_tcp_syn_retries只能通过sysctl机制设置。
所以我没有看到服务器上的syncookies对connect()超时有任何影响。正如你所指出的那样,这是有道理的。客户怎么知道服务器正在使用syncookies?特别是在收到syn | ack之前,它将完成connect()。
我猜测作者试图传达应该将超时设置得相对较高,因为随着syncookies的出现,完全积压的服务器仍然可以绕过成功建立连接,但可能需要一段时间(请注意,此行可以追溯到当前man-pages repo设置之前,因为它是在2004年首次导入man-pages 1.70时引入的)。
答案 1 :(得分:0)
Syncookies用于阻止同步洪水。生成它们并验证它们需要一些时间。如果您的客户端断开连接,我认为它可能会等待相应的64秒以生成新的5个顶部位:t mod 32,
其中t
是一个32位时间计数器,每64秒增加一次
这就是我的假设:至少它与验证服务器和客户端占用一些时间有关。