linux 2.6.26.3的结果如下,2.6.11貌似是一样的,估计版本之间没什么差别
这是linux判断是否超出backlog的方法
比如backlog 是5,那么真时的连接允许保持6条,sk_ack_backlog = 0为默认值
再第7次连接时才返回真(第一次为0,..第6次为5,5==5)
static inline int sk_acceptq_is_full(struct sock *sk)
{
return sk->sk_ack_backlog > sk->sk_max_ack_backlog;
}
对于别的backlog类似,这可能是为了处理backlog == 0的情况(unp说对于0的解释不同实现不同,这就是linux的解释,至少允许1个连接)
为了说明情况我以backlog为1为例子,为5也一样,但是省的改flw给的c代码
当第一个connect来时,ok连接成功,sk_ack_backlog(0) > sk_max_ack_backlog(1) 不成立
第2个连接时,连接一样成功 sk_ack_backlog(1) > sk_max_ack_backlog(1) 不成立
到第3个时,full了,这个条件的判断是在收到connect发出3次握手中的第3个包,即ack包时检查的
代码如下
listen_overflow:
printk("%s %d: overflow\n", __func__, __LINE__);
if (!sysctl_tcp_abort_on_overflow) {
inet_rsk(req)->acked = 1;
return NULL;
}
embryonic_reset:
printk("%s %d: reset\n", __func__, __LINE__);
NET_INC_STATS_BH(LINUX_MIB_EMBRYONICRSTS);
if (!(flg & TCP_FLAG_RST))
req->rsk_ops->send_reset(sk, skb);
inet_csk_reqsk_queue_drop(sk, req, prev);
return NULL;
|
printk是我加的
代码我没有继续跟踪,但是很明显:
如果sysctl_tcp_abort_on_overflow为0
(默认值/proc/sys/net/ipv4/tcp_abort_on_overflow)是,那么只是是丢弃最后的ack包(当然客户端不会知道,
这也是flw说的客户认为连接的原因,客户ack出去就连接完成了),后果和服务器没收到ack包是一样的,如果客户这个时候直接read,write,
服务器可想而知,会重传syn-ack包,因为它“没收到”ack(即它还在等ack),事实是,即使客户不操作,服务器也会重发syn-ack,原因很
简单,3次握手要完成
如果sysctl_tcp_abort_on_overflow不为0,那么直接rst了,当然connect不会知道,基于同样的理由,connect已经返回了,读写时就会知道被reset这个事实了
这些我想都是可以完全试验的,但是看代码以及printk,加上抓包,已经很明显了
以下是本人添加
从tcpdump抓包的结果看,客户端每9秒建立两条连接,也就是服务端延迟9秒对客户端的syn包进行回应;但是,当syn_recv状态已经开始退出的时候就变为每3建立一条连接
9秒回应抓包如下:(测试程序的服务端没有调用accept)
tcpdump -i lo port 9999 -r hw.tcp|grep 32790
reading from file hw.tcp, link-type EN10MB (Ethernet)
10:30:15.289296 IP 192.168.0.130.32790 > 192.168.0.130.9999: S 1650969640:1650969640(0) win 32767
10:30:18.288480 IP 192.168.0.130.32790 > 192.168.0.130.9999: S 1650969640:1650969640(0) win 32767
10:30:24.288311 IP 192.168.0.130.32790 > 192.168.0.130.9999: S 1650969640:1650969640(0) win 32767
10:30:24.288343 IP 192.168.0.130.9999 > 192.168.0.130.32790: S 1652955109:1652955109(0) ack 1650969641 win 32767
10:30:24.288362 IP 192.168.0.130.32790 > 192.168.0.130.9999: . ack 1 win 4096
10:30:27.686649 IP 192.168.0.130.9999 > 192.168.0.130.32790: S 1652955109:1652955109(0) ack 1650969641 win 32767
10:30:27.686690 IP 192.168.0.130.32790 > 192.168.0.130.9999: . ack 1 win 4096
10:30:33.685473 IP 192.168.0.130.9999 > 192.168.0.130.32790: S 1652955109:1652955109(0) ack 1650969641 win 32767
10:30:33.685509 IP 192.168.0.130.32790 > 192.168.0.130.9999: . ack 1 win 4096
10:30:45.686130 IP 192.168.0.130.9999 > 192.168.0.130.32790: S 1652955109:1652955109(0) ack 1650969641 win 32767
10:30:45.686160 IP 192.168.0.130.32790 > 192.168.0.130.9999: . ack 1 win 4096
bash-3.00# tcpdump -i lo port 9999 -r hw.tcp|grep 32791
reading from file hw.tcp, link-type EN10MB (Ethernet)
10:30:24.288493 IP 192.168.0.130.32791 > 192.168.0.130.9999: S 1661414239:1661414239(0) win 32767
10:30:24.288509 IP 192.168.0.130.9999 > 192.168.0.130.32791: S 1661567750:1661567750(0) ack 1661414240 win 32767
10:30:24.288523 IP 192.168.0.130.32791 > 192.168.0.130.9999: . ack 1 win 4096
10:30:27.686663 IP 192.168.0.130.9999 > 192.168.0.130.32791: S 1661567750:1661567750(0) ack 1661414240 win 32767
10:30:27.686700 IP 192.168.0.130.32791 > 192.168.0.130.9999: . ack 1 win 4096
10:30:33.685485 IP 192.168.0.130.9999 > 192.168.0.130.32791: S 1661567750:1661567750(0) ack 1661414240 win 32767
10:30:33.685517 IP 192.168.0.130.32791 > 192.168.0.130.9999: . ack 1 win 4096
10:30:45.886100 IP 192.168.0.130.9999 > 192.168.0.130.32791: S 1661567750:1661567750(0) ack 1661414240 win 32767
10:30:45.886148 IP 192.168.0.130.32791 > 192.168.0.130.9999: . ack 1 win 4096
3秒回应抓包如下:
tcpdump port 9999 -r hw7.tcp | grep 55145
reading from file hw7.tcp, link-type EN10MB (Ethernet)
11:33:35.354033 IP pc-200805111531.unimassystem.com.55145 > 192.168.0.130.9999: S 766929119:766929119(0) win 5840
11:33:38.353957 IP pc-200805111531.unimassystem.com.55145 > 192.168.0.130.9999: S 766929119:766929119(0) win 5840
11:33:38.354004 IP 192.168.0.130.9999 > pc-200805111531.unimassystem.com.55145: S 1149964455:1149964455(0) ack 766929120 win 5792
11:33:38.354272 IP pc-200805111531.unimassystem.com.55145 > 192.168.0.130.9999: . ack 1 win 1460
11:33:42.153595 IP 192.168.0.130.9999 > pc-200805111531.unimassystem.com.55145: S 1149964455:1149964455(0) ack 766929120 win 5792
11:33:42.153842 IP pc-200805111531.unimassystem.com.55145 > 192.168.0.130.9999: . ack 1 win 1460
11:33:48.152723 IP 192.168.0.130.9999 > pc-200805111531.unimassystem.com.55145: S 1149964455:1149964455(0) ack 766929120 win 5792
11:33:48.152932 IP pc-200805111531.unimassystem.com.55145 > 192.168.0.130.9999: . ack 1 win 1460
11:34:00.350861 IP 192.168.0.130.9999 > pc-200805111531.unimassystem.com.55145: S 1149964455:1149964455(0) ack 766929120 win 5792
11:34:00.351157 IP pc-200805111531.unimassystem.com.55145 > 192.168.0.130.9999: . ack 1 win 1460
bash-3.00# tcpdump port 9999 -r hw7.tcp | grep 55146
reading from file hw7.tcp, link-type EN10MB (Ethernet)
11:33:38.354339 IP pc-200805111531.unimassystem.com.55146 > 192.168.0.130.9999: S 775886579:775886579(0) win 5840
11:33:41.354160 IP pc-200805111531.unimassystem.com.55146 > 192.168.0.130.9999: S 775886579:775886579(0) win 5840
11:33:41.354205 IP 192.168.0.130.9999 > pc-200805111531.unimassystem.com.55146: S 1152059511:1152059511(0) ack 775886580 win 5792
11:33:41.354549 IP pc-200805111531.unimassystem.com.55146 > 192.168.0.130.9999: . ack 1 win 1460
11:33:45.552521 IP 192.168.0.130.9999 > pc-200805111531.unimassystem.com.55146: S 1152059511:1152059511(0) ack 775886580 win 5792
11:33:45.552894 IP pc-200805111531.unimassystem.com.55146 > 192.168.0.130.9999: . ack 1 win 1460
11:33:51.551634 IP 192.168.0.130.9999 > pc-200805111531.unimassystem.com.55146: S 1152059511:1152059511(0) ack 775886580 win 5792
11:33:51.551956 IP pc-200805111531.unimassystem.com.55146 > 192.168.0.130.9999: . ack 1 win 1460
11:34:03.549851 IP 192.168.0.130.9999 > pc-200805111531.unimassystem.com.55146: S 1152059511:1152059511(0) ack 775886580 win 5792
11:34:03.550073 IP pc-200805111531.unimassystem.com.55146 > 192.168.0.130.9999: . ack 1 win 1460
bash-3.00#
阅读(2908) | 评论(0) | 转发(0) |