[应用相关]

LwIP BUG之TCP连接丢失

[复制链接]
743|3
手机看帖
扫描二维码
随时随地手机跟帖
labasi|  楼主 | 2018-9-15 21:44 | 显示全部楼层 |阅读模式

注:本文转自老衲五木的博客!

LwIP所有版本包括最新的2.0版本具有以下缺陷,当用户使用raw编程并在err或poll回调函数中操作了内核全局tcp_active_pcbs链表(最典型的,比如进行了重连操作),将有可能导致链表异常,严重情况下,链表中的很多tcp_pcb会丢失,从而导致部分连接没有任何反应,出现假死的现象。
    具体信息为(以1.4.1为例),在tcp.c文件的tcp_slowtmr函数中,截取如下部分。
    请参考下面的蓝色步骤(1)->(2)->(3)->(4)->(5)->(6),该流程路径会引发问题。代码第10行为需要添加的代码以修正这个BUG。



  • tcp_slowtmr_start:



  • prev = NULL;



  • pcb = tcp_active_pcbs;



  • if (pcb == NULL) {



  •         LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n"));



  • }



  • while (pcb != NULL) {



  •         if (pcb->last_timer == tcp_timer_ctr) {        //(4)已经处理过的连接不再被处理







  •           prev = pcb;                                 //需要在源代码中加上这句,否则会引起tcp_pcb丢失



  •           pcb = pcb->next;



  •           continue;



  • }



  • pcb->last_timer = tcp_timer_ctr;



  • ....







  • if (pcb_remove) {                                 //(1)某种错误后需要移除连接  //(5)第二次循环,如果也出现有需要移除的连接



  •         if (prev != NULL) {



  •                 prev->next = pcb->next;



  •         } else {



  •                 tcp_active_pcbs = pcb->next;        //(6)如果不加红色部分,则代码直接进入这里,tcp_active_pcbs被强制改写成pcb->next, 节点丢失!!!!!



  •         }







  •         tcp_active_pcbs_changed = 0;



  •         TCP_EVENT_ERR(err_fn, err_arg, ERR_ABRT);         //(2)这里可能进行重连操作



  •         if (tcp_active_pcbs_changed) {  



  •                 goto tcp_slowtmr_start;         //(3)重连后跳回到标号tcp_slowtmr_start



  •         }



  • }




该问题发生的场景:至少有两个TCP客户端,并且两个客户端在会在err或者poll回调函数中进行重连,系统里面可以存在其他多个tcp连接(服务器或客户端均可)。如果前述两个客户端启动后,对应的两个服务器均不在线(或者通信过程中poll发生错误),则这两个客户端会不断在err回调函数中进行重连,重连将引发上述(1)~(6)的步骤,从而引起全局链表中其他正常控制块消失,其他连接假死。




mmuuss586| | 2018-12-23 17:51 | 显示全部楼层
感谢分享

使用特权

评论回复
labasi|  楼主 | 2019-1-1 16:51 | 显示全部楼层
版主客气啦

使用特权

评论回复
tototm| | 2019-2-4 22:24 | 显示全部楼层
谢谢分享,正为这个发愁!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

44

主题

3308

帖子

2

粉丝