加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

LWIP完全剖析详解之core/tcp.c

(2016-05-26 16:29:15)
分类: LWIP
#include "lwipopt.h" //选项头文件,lwip一些配置的选项包含在opt.h,debug开启和内存大小等配置信息  
  
#if LWIP_TCP  
  
#include "lwip/def.h" //定义项头文件,包括一些宏  
#include "lwip/mem.h" //内存头文件,包括一些宏,内存大小,申请内存,内存对齐  
#include "lwip/memp.h" //内存池头文件,包含内存申请,内存释放  
#include "lwip/snmp.h" //SNMP(Simple Network Management Protocol,简单网络管理协议),包含snmp的函数声明  
#include "lwip/tcp.h" //包含tcp.c里面定义的函数声明和所用到的宏  
#include "lwip/debug.h" //包含lwip debug的一些宏,开启debug  
  
#include  
  
 
 
u32_t tcp_ticks; //定义tcp的滴答数      
const u8_t tcp_backoff[13] =  
    { 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7};  
   
   
const u8_t tcp_persist_backoff[7] = { 3, 6, 12, 24, 48, 96, 120 };  
  
 
 
 
 
struct tcp_pcb *tcp_bound_pcbs;    
 
  
 
union tcp_listen_pcbs_t tcp_listen_pcbs;  
  
 
 
struct tcp_pcb *tcp_active_pcbs;    
  
 
 
struct tcp_pcb *tcp_tw_pcbs;  
  
 
struct tcp_pcb *tcp_tmp_pcb;  
  
 
static u8_t tcp_timer;  
  
 
static u16_t tcp_new_port(void);  
  
 
 
void  
tcp_tmr(void)  
{  
   
   
  tcp_fasttmr();  
  
  if (++tcp_timer & 1) {//tcp_timer加1后与1  
     
     
    tcp_slowtmr();  
  }  
}  
  
 
 
err_t  
tcp_close(struct tcp_pcb *pcb)  
{  
  err_t err;  
  
  //TCP debug信息,打印pcb的状态  
#if TCP_DEBUG  
  LWIP_DEBUGF(TCP_DEBUG, ("tcp_close: closing in "));  
  tcp_debug_print_state(pcb->state);  
#endif  
  
  switch (pcb->state) {  
  case CLOSED:  
     
  
     
    err = ERR_OK;//设定返回值  
    TCP_RMV(&tcp_bound_pcbs, pcb);//从绑定的pcb列表中去掉pcb  
    memp_free(MEMP_TCP_PCB, pcb);//在MEMP_TCP_PCB内存池设定释放掉的pcb对应的单元值,释放内存  
    pcb = NULL; //设置pcb指针指向空  
    break;  
  case LISTEN:  
    err = ERR_OK;//设定返回值  
    tcp_pcb_remove((struct tcp_pcb **)&tcp_listen_pcbs.pcbs, pcb);//在tcp PCB监听列表中删除对应的pcb  
    memp_free(MEMP_TCP_PCB_LISTEN, pcb);//在MEMP_TCP_PCB_LISTEN对应的内存池中设定需要释放的pcb单元值  
    pcb = NULL;//设置pcb指针指向空  
    break;  
  case SYN_SENT:  
    err = ERR_OK;//设定返回值  
    tcp_pcb_remove(&tcp_active_pcbs, pcb);//在所有accept或者send数据状态的TCP PCB列表的TCP PCB列表中删除对应的pcb  
    memp_free(MEMP_TCP_PCB, pcb);//在MEMP_TCP_PCB内存池设定释放掉的pcb对应的单元值,释放内存  
    pcb = NULL;//设置pcb指针指向空  
    snmp_inc_tcpattemptfails();//tcp尝试失败  
    break;  
  case SYN_RCVD:  
    err = tcp_send_ctrl(pcb, TCP_FIN);//通过pcb发送对应的TCP_FIN包,表示已完成  
    if (err == ERR_OK) { //如果发回ERR_OK表明发送成功  
      snmp_inc_tcpattemptfails();//tcp 尝试失败  
      pcb->state = FIN_WAIT_1; //pcb进入FIN_WAIT_1状态  
    }  
    break;  
  case ESTABLISHED:  
    err = tcp_send_ctrl(pcb, TCP_FIN);//通过pcb发送对应的TCP_FIN包,表示已完成  
    if (err == ERR_OK) {//如果发回ERR_OK表明发送成功  
      snmp_inc_tcpestabresets();//tcp 建立连接复位  
      pcb->state = FIN_WAIT_1; //pcb进入FIN_WAIT_1状态  
    }  
    break;  
  case CLOSE_WAIT:  
    err = tcp_send_ctrl(pcb, TCP_FIN);//通过pcb发送对应的TCP_FIN包,表示已完成  
    if (err == ERR_OK) {//如果发回ERR_OK表明发送成功  
      snmp_inc_tcpestabresets();//tcp 建立连接复位  
      pcb->state = LAST_ACK;//pcb进入LAST_ACK状态  
    }  
    break;  
  default:  
     
     
    err = ERR_OK;//设置返回值  
    pcb = NULL;//把pcb指向NULL  
    break;  
  }  
  
  if (pcb != NULL && err == ERR_OK) {  
     
     
     
    tcp_output(pcb);//发送pcb对应的包  
  }  
  return err;  
}  
  
 
 
void  
tcp_abandon(struct tcp_pcb *pcb, int reset)  
{  
  u32_t seqno, ackno;//定义序列号,应答号  
  u16_t remote_port, local_port;//远程端口,本地端口  
  struct ip_addr remote_ip, local_ip;//远程IP地址结构体,本地IP地址结构体  
#if LWIP_CALLBACK_API  //LWIP是否要使用回调API  
  void (* errf)(void *arg, err_t err);//定义回调函数指针  
#endif  
  void *errf_arg;  
    
   
   
  if (pcb->state == TIME_WAIT) { //如果pcb状态值是TIME_WAIT  
    tcp_pcb_remove(&tcp_tw_pcbs, pcb);//从time-wait等待状态列表中删除pcb  
    memp_free(MEMP_TCP_PCB, pcb);//删除pcb内存  
  } else {//否则  
    seqno = pcb->snd_nxt;//序列号指向发送下一个  
    ackno = pcb->rcv_nxt;//应答好指向接收到的下一个  
    ip_addr_set(&local_ip, &(pcb->local_ip));//设置pcb中的本地地址  
    ip_addr_set(&remote_ip, &(pcb->remote_ip));//设置pcb中的远端地址  
    local_port = pcb->local_port;  
    remote_port = pcb->remote_port;  
#if LWIP_CALLBACK_API  
    errf = pcb->errf;//指针指向回调函数  
#endif  
    errf_arg = pcb->callback_arg;//回调参数  
    tcp_pcb_remove(&tcp_active_pcbs, pcb);//把pcb重激活的tcp pcb列表中删除  
    if (pcb->unacked != NULL) {//发送还没有回答?  
      tcp_segs_free(pcb->unacked);//释放未应答段  
    }  
    if (pcb->unsent != NULL) {//还没有发送?  
      tcp_segs_free(pcb->unsent);//释放还没有发送段  
    }  
#if TCP_QUEUE_OOSEQ    //TCP队列乱序  
    if (pcb->ooseq != NULL) {//队列乱?  
      tcp_segs_free(pcb->ooseq);//释放乱队列  
    }  
#endif  
    memp_free(MEMP_TCP_PCB, pcb);//释放pcb  
    TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT);//调用回调函数,传入终止错误参数  
    if (reset) {//复位?  
      LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abandon: sending RST\n"));//打印发送RST信息  
      tcp_rst(seqno, ackno, &local_ip, &remote_ip, local_port, remote_port);//tcp发送复位信息包  
    }  
  }  
}  
  
 
 
err_t  
tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)  
{  
  struct tcp_pcb *cpcb; //定义cpcb  
  
  LWIP_ERROR("tcp_bind: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_ISCONN);  
  
  if (port == 0) { //端口为0则从本地找一个端口  
    port = tcp_new_port();  
  }  
   
   
  //检查是不是地址已经在使用  
  for(cpcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs;  
      cpcb != NULL; cpcb = cpcb->next) {  
    if (cpcb->local_port == port) {//端口是否在使用  
      if (ip_addr_isany(&(cpcb->local_ip)) ||  
          ip_addr_isany(ipaddr) ||  
          ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {  
        return ERR_USE;//返回在使用  
      }  
    }  
  }  
   
   
  for(cpcb = tcp_active_pcbs;  
      cpcb != NULL; cpcb = cpcb->next) {  
    if (cpcb->local_port == port) {//端口是否在使用  
      if (ip_addr_isany(&(cpcb->local_ip)) ||  
          ip_addr_isany(ipaddr) ||  
          ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {  
        return ERR_USE;//返回在使用  
      }  
    }  
  }  
   
   
  for(cpcb = tcp_bound_pcbs; cpcb != NULL; cpcb = cpcb->next) {  
    if (cpcb->local_port == port) {//端口是否在使用  
      if (ip_addr_isany(&(cpcb->local_ip)) ||  
          ip_addr_isany(ipaddr) ||  
          ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {  
        return ERR_USE;//返回在使用  
      }  
    }  
  }  
   
   
  for(cpcb = tcp_tw_pcbs; cpcb != NULL; cpcb = cpcb->next) {  
    if (cpcb->local_port == port) {//端口是否在使用  
      if (ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {  
        return ERR_USE;//返回在使用  
      }  
    }  
  }  
  
  if (!ip_addr_isany(ipaddr)) {//检查是否为所有本地IP地址  
    pcb->local_ip = *ipaddr;  
  }  
  pcb->local_port = port;//设定本地端口  
  TCP_REG(&tcp_bound_pcbs, pcb);//注册绑定的pcb  
  LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %"U16_F"\n", port));  
  return ERR_OK;//返回绑定成功  
}  
#if LWIP_CALLBACK_API  
 
 
static err_t  
tcp_accept_null(void *arg, struct tcp_pcb *pcb, err_t err)  
{  
  LWIP_UNUSED_ARG(arg);//没使用的参数  
  LWIP_UNUSED_ARG(pcb);//没使用的参数  
  LWIP_UNUSED_ARG(err);//没使用的参数  
  
  return ERR_ABRT;//返回终止  
}  
#endif  
  
 
 
struct tcp_pcb *  
tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)  
{  
  struct tcp_pcb_listen *lpcb;//定义监听协议控制块  
  
  LWIP_UNUSED_ARG(backlog);//不用参数  
  LWIP_ERROR("tcp_listen: pcb already connected", pcb->state == CLOSED, return NULL);  
  //判断pcb状态是否关闭  
  
   
  //已经在监听中?  
  if (pcb->state == LISTEN) {  
    return pcb;//返回  
  }  
  lpcb = memp_malloc(MEMP_TCP_PCB_LISTEN);//分配MEMP_TCP_PCB_LISTEN内存  
  if (lpcb == NULL) {//分配不成功  
    return NULL;//退出  
  }  
  lpcb->callback_arg = pcb->callback_arg;//回调参数  
  lpcb->local_port = pcb->local_port;//本地端口  
  lpcb->state = LISTEN;//标志为监听状态  
  lpcb->so_options = pcb->so_options;//Socket选项  
  lpcb->so_options |= SOF_ACCEPTCONN;//socket 已经监听  
  lpcb->ttl = pcb->ttl;//存活时间  
  lpcb->tos = pcb->tos;//服务类型  
  ip_addr_set(&lpcb->local_ip, &pcb->local_ip);//设置本地IP  
  TCP_RMV(&tcp_bound_pcbs, pcb);//把pcb从tcp绑定列表中删除  
  memp_free(MEMP_TCP_PCB, pcb);//释放空间  
#if LWIP_CALLBACK_API  
  lpcb->accept = tcp_accept_null; //设置接受函数为空  
#endif  
#if TCP_LISTEN_BACKLOG  
  lpcb->accepts_pending = 0;//接受挂起清空  
  lpcb->backlog = (backlog ? backlog : 1);//累积>0?否则1  
#endif  
  TCP_REG(&tcp_listen_pcbs.listen_pcbs, lpcb);//注册lpcb进监听列表  
  return (struct tcp_pcb *)lpcb;//返回监听的块  
}  
  
 
 
u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb)//TCP 更新接收发布窗口  
{  
  u32_t new_right_edge = pcb->rcv_nxt + pcb->rcv_wnd;//下一个序列号+接收窗口  
  
  if (TCP_SEQ_GEQ(new_right_edge, pcb->rcv_ann_right_edge + pcb->mss)) {//比较是否越界  
     
     
    pcb->rcv_ann_wnd = pcb->rcv_wnd;//接收发布窗口设置为接收窗口  
    return new_right_edge - pcb->rcv_ann_right_edge;//得到剩下的发布窗口  
  } else {  
    if (TCP_SEQ_GT(pcb->rcv_nxt, pcb->rcv_ann_right_edge)) {//如果期待的下一个序列号大于发布边界  
       
       
      pcb->rcv_ann_wnd = 0;//发布窗口置0  
    } else {  
       
       
      pcb->rcv_ann_wnd = pcb->rcv_ann_right_edge - pcb->rcv_nxt;  
    }  
    return 0;  
  }  
}  
  
 
 
void  
tcp_recved(struct tcp_pcb *pcb, u16_t len)  
{  
  int wnd_inflation;//定义窗口膨胀变量  
  
  LWIP_ASSERT("tcp_recved: len would wrap rcv_wnd\n",  
              len <= 0xffff - pcb->rcv_wnd );  
  
  pcb->rcv_wnd += len;//接收到的窗口加len  
  if (pcb->rcv_wnd > TCP_WND)//大于TCP_WND?  
    pcb->rcv_wnd = TCP_WND;//职位最大的窗口值  
  
  wnd_inflation = tcp_update_rcv_ann_wnd(pcb);//更新发布窗口,返回剩下的值  
  
   
   
  if (wnd_inflation >= TCP_WND_UPDATE_THRESHOLD) //返回的值大于TCP窗口更新的临界值  
    tcp_ack_now(pcb);//tcp应答  
  
  LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: recveived %"U16_F" bytes, wnd %"U16_F" (%"U16_F").\n",  
         len, pcb->rcv_wnd, TCP_WND - pcb->rcv_wnd));  
}  
  
 
 
static u16_t  
tcp_new_port(void)  
{  
  struct tcp_pcb *pcb;  
#ifndef TCP_LOCAL_PORT_RANGE_START    
#define TCP_LOCAL_PORT_RANGE_START 4096//端口范围开始  
#define TCP_LOCAL_PORT_RANGE_END   0x7fff//端口范围结束  
#endif  
  static u16_t port = TCP_LOCAL_PORT_RANGE_START;//开始端口  
    
 again:  
  if (++port > TCP_LOCAL_PORT_RANGE_END) {//是否超出范围  
    port = TCP_LOCAL_PORT_RANGE_START;//超出,则回到开始  
  }  
    
  for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {//在激活的列表中循环尝试  
    if (pcb->local_port == port) {//已被使用  
      goto again;//下一个  
    }  
  }  
  for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {//在等待的列表中循环尝试  
    if (pcb->local_port == port) {//已被使用  
      goto again;//下一个  
    }  
  }  
  for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) {//在监听的列表中循环尝试  
    if (pcb->local_port == port) {//已被使用  
      goto again;//下一个  
    }  
  }  
  return port;  
}  
  
 
 
err_t  
tcp_connect(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port,  
      err_t (* connected)(void *arg, struct tcp_pcb *tpcb, err_t err))  
{  
  err_t ret;  
  u32_t iss;  
  
  LWIP_ERROR("tcp_connect: can only connected from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN);  
  
  LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port));  
  if (ipaddr != NULL) {//如果传入的地址不为空  
    pcb->remote_ip = *ipaddr;//远程ip赋值  
  } else {  
    return ERR_VAL;//返回错误值  
  }  
  pcb->remote_port = port;//设置远程端口  
  if (pcb->local_port == 0) {//本地端口为0  
    pcb->local_port = tcp_new_port();//申请新端口  
  }   
  iss = tcp_next_iss();//计算一个新的初始化序列号给新的连接  
  pcb->rcv_nxt = 0;//接收的下一个为0  
  pcb->snd_nxt = iss;//发送的下一个为初始化序列号  
  pcb->lastack = iss - 1;//ack减一  
  pcb->snd_lbb = iss - 1;// 下一个字节序列号缓冲  
  pcb->rcv_wnd = TCP_WND;//接收窗口数  
  pcb->rcv_ann_wnd = TCP_WND;//接收发布窗口数  
  pcb->rcv_ann_right_edge = pcb->rcv_nxt;//发布正确边缘  
  pcb->snd_wnd = TCP_WND;//发送窗口数  
   
   
  pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS;  
#if TCP_CALCULATE_EFF_SEND_MSS  
  pcb->mss = tcp_eff_send_mss(pcb->mss, ipaddr);//计算有效发送的最大段大小   
#endif  
  pcb->cwnd = 1;//避免拥挤  
  pcb->ssthresh = pcb->mss * 10;//控制值  
  pcb->state = SYN_SENT;//设置同步发送  
#if LWIP_CALLBACK_API    
  pcb->connected = connected;//连接回调函数  
#endif  
  TCP_RMV(&tcp_bound_pcbs, pcb);//从绑定列表中删除pcb  
  TCP_REG(&tcp_active_pcbs, pcb);//注册激活的pcb到激活列表  
  
  snmp_inc_tcpactiveopens();//开启tcp激活  
    
  //pcb假如tcp队列  
  ret = tcp_enqueue(pcb, NULL, 0, TCP_SYN, 0, TF_SEG_OPTS_MSS  
#if LWIP_TCP_TIMESTAMPS  
                    | TF_SEG_OPTS_TS  
#endif  
                    );  
  if (ret == ERR_OK) { //OK?  
    tcp_output(pcb);//发送数据包  
  }  
  return ret;//返回结果  
}   
  
 
 
void  
tcp_slowtmr(void)  
{  
  struct tcp_pcb *pcb, *pcb2, *prev;  
  u16_t eff_wnd;// 有效窗口  
  u8_t pcb_remove;        
  err_t err;  
  
  err = ERR_OK;  
  
  ++tcp_ticks;//tcp滴答数+1  
  
   
   
  prev = NULL;  
  pcb = tcp_active_pcbs;  
  if (pcb == NULL) {  
    LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n"));  
  }  
  while (pcb != NULL) {//遍历激活的pcb列表  
    LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb\n"));  
    LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED);  
    LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN);  
    LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT);  
  
    pcb_remove = 0;  
  
    if (pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) {//如果状态为SYN_SENT而且pcb传播编号是TCP_SYNMAXRTX  
      ++pcb_remove;//移除计数加1  
      LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n"));  
    }  
    else if (pcb->nrtx == TCP_MAXRTX) {//pcb传播编号是TCP_SYNMAXRTX  
      ++pcb_remove;//移除计数加1  
      LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n"));  
    } else {  
      if (pcb->persist_backoff > 0) {  
         
         
        pcb->persist_cnt++;//持续计时器计数  
        if (pcb->persist_cnt >= tcp_persist_backoff[pcb->persist_backoff-1]) {//tcp持续备值  
          pcb->persist_cnt = 0;  
          if (pcb->persist_backoff < sizeof(tcp_persist_backoff)) {//如果pcb持续备值小雨tcp_persist_backoff的大小  
            pcb->persist_backoff++;//加1  
          }  
          tcp_zero_window_probe(pcb);//发送持续计时器零窗口探头  
        }  
      } else {  
         
         
        if(pcb->rtime >= 0)  
          ++pcb->rtime;  
  
        if (pcb->unacked != NULL && pcb->rtime >= pcb->rto) {//  
           
           
          LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %"S16_F  
                                      " pcb->rto %"S16_F"\n",  
                                      pcb->rtime, pcb->rto));  
  
           
           
          if (pcb->state != SYN_SENT) {//pcb不在SYN_SENT  
            pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx];//计算出重发时间  
          }  
  
           
           
          pcb->rtime = 0;  
  
           
           
          eff_wnd = LWIP_MIN(pcb->cwnd, pcb->snd_wnd);//计算有效窗口  
          pcb->ssthresh = eff_wnd >> 1;//有效值右移1位  
          if (pcb->ssthresh < pcb->mss) {//阀门值小于最大段大小?  
            pcb->ssthresh = pcb->mss * 2;  
          }  
          pcb->cwnd = pcb->mss;//最大段大小赋给拥挤窗口  
          LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: cwnd %"U16_F  
                                       " ssthresh %"U16_F"\n",  
                                       pcb->cwnd, pcb->ssthresh));  
   
           
           
          tcp_rexmit_rto(pcb);//为重发重新入队所有的未应答段  
        }  
      }  
    }  
     
     
    if (pcb->state == FIN_WAIT_2) {//检测状态  
      if ((u32_t)(tcp_ticks - pcb->tmr) >  
          TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) {//tcp滴答数减去计时器的计数 是否大于等待的时间除以粗粒超时?  
        ++pcb_remove;//删除多一个pcb  
        LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n"));  
      }  
    }  
  
     
     
    if((pcb->so_options & SOF_KEEPALIVE) &&   
       ((pcb->state == ESTABLISHED) ||   
        (pcb->state == CLOSE_WAIT))) {//在SOF_KEEPALIVE的情况下且是ESTABLISHED或CLOSE_WAIT状态  
#if LWIP_TCP_KEEPALIVE  
      if((u32_t)(tcp_ticks - pcb->tmr) >   
         (pcb->keep_idle + (pcb->keep_cnt*pcb->keep_intvl))  
         / TCP_SLOW_INTERVAL)//如果是KEEPALIVE被打开,允许计数keep alive的间隔  
#else        
      if((u32_t)(tcp_ticks - pcb->tmr) >   
         (pcb->keep_idle + TCP_MAXIDLE) / TCP_SLOW_INTERVAL)//最大的闲置Keep alive  
#endif  
      {  
        LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to %"U16_F".%"U16_F".%"U16_F".%"U16_F".\n",  
                                ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),  
                                ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip)));  
          
        tcp_abort(pcb);//终止pcb  
      }  
#if LWIP_TCP_KEEPALIVE  
      else if((u32_t)(tcp_ticks - pcb->tmr) >   
              (pcb->keep_idle + pcb->keep_cnt_sent * pcb->keep_intvl)  
              / TCP_SLOW_INTERVAL)//如果是KEEPALIVE被打开,允许发送计数keep alive的间隔  
#else  
      else if((u32_t)(tcp_ticks - pcb->tmr) >   
              (pcb->keep_idle + pcb->keep_cnt_sent * TCP_KEEPINTVL_DEFAULT)   
              / TCP_SLOW_INTERVAL)//最大的闲置发送计数*默认Keep alive间隔  
#endif  
      {  
        tcp_keepalive(pcb);//keepalive pcb  
        pcb->keep_cnt_sent++;//计数加1  
      }  
    }  
  
     
     
#if TCP_QUEUE_OOSEQ      
    if (pcb->ooseq != NULL &&  
        (u32_t)tcp_ticks - pcb->tmr >= pcb->rto * TCP_OOSEQ_TIMEOUT) {  
      tcp_segs_free(pcb->ooseq);//释放超出序列段  
      pcb->ooseq = NULL;  
      LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: dropping OOSEQ queued data\n"));  
    }  
#endif  
  
     
     
    if (pcb->state == SYN_RCVD) {  
      if ((u32_t)(tcp_ticks - pcb->tmr) >  
          TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) {//超时了?  
        ++pcb_remove;//移除加1  
        LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n"));  
      }  
    }  
  
     
     
    if (pcb->state == LAST_ACK) {  
      if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {//超时了?  
        ++pcb_remove;//移除数加1  
        LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in LAST-ACK\n"));  
      }  
    }  
  
     
     
    if (pcb_remove) {  
      tcp_pcb_purge(pcb);      //清理一个TCP PCB  
       
       
      if (prev != NULL) {//前一个为空?  
        LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs);  
        prev->next = pcb->next;//下一个指向pcb的next  
      } else {  
         
         
        LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb);  
        tcp_active_pcbs = pcb->next;//直接把tcp_active_pcbs队列执行pcb的下一个  
      }  
  
      TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_ABRT);//TCP错误发生事件  
  
      pcb2 = pcb->next;//pcb2指向pcb的next  
      memp_free(MEMP_TCP_PCB, pcb);//释放pcb  
      pcb = pcb2;//pcb指向往下的一个  
    } else {  
  
       
       
      ++pcb->polltmr;//调查计时器加1  
      if (pcb->polltmr >= pcb->pollinterval) {//计数器大于调查间隔  
        pcb->polltmr = 0;//调查计数器置0  
        LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n"));  
        TCP_EVENT_POLL(pcb, err);//TCP调查事件  
        if (err == ERR_OK) {//错误?  
          tcp_output(pcb);//发送pcb数据  
        }  
      }  
        
      prev = pcb;//前一个指向pcb  
      pcb = pcb->next;//pcb指向pcb的下一个  
    }  
  }  
    
   
   
  prev = NULL;      
  pcb = tcp_tw_pcbs;//pcb指向time wait pcb列表  
  while (pcb != NULL) {  
    LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);  
    pcb_remove = 0;//移除计数设置0  
  
     
     
    if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {  
      ++pcb_remove;//pcb移除技术加1  
    }  
      
  
     
     
    if (pcb_remove) {  
      tcp_pcb_purge(pcb); //清理pcb  
       
       
      if (prev != NULL) {  
        LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs);  
        prev->next = pcb->next;//摘除pcb  
      } else {  
         
         
        LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb);  
        tcp_tw_pcbs = pcb->next;//摘除  
      }  
      pcb2 = pcb->next;//pcb2指向pcb的下一个  
      memp_free(MEMP_TCP_PCB, pcb);//释放pcb  
      pcb = pcb2;  
    } else {//否则不应该移除  
      prev = pcb;//前面的指针指向pcb  
      pcb = pcb->next;//pcb指向下一个  
    }  
  }  
}  
  
 
 
void  
tcp_fasttmr(void)  
{  
  struct tcp_pcb *pcb;  
  
  for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { //遍历tcp_active_pcbs列表  
     
     
    if (pcb->refused_data != NULL) {  
       
       
      err_t err;  
      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_fasttmr: notify kept packet\n"));  
      TCP_EVENT_RECV(pcb, pcb->refused_data, ERR_OK, err);//  
      if (err == ERR_OK) {  
        pcb->refused_data = NULL;//拒绝数据置空  
      }  
    }  
  
       
       
    if (pcb->flags & TF_ACK_DELAY) {  
      LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n"));  
      tcp_ack_now(pcb);//输出应答PCB包  
      pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);//设置标志位,取消延迟ACK和立即ACK  
    }  
  }  
}  
  
 
 
u8_t  
tcp_segs_free(struct tcp_seg *seg)  
{  
  u8_t count = 0;//置0  
  struct tcp_seg *next;//tcp段下一个  
  while (seg != NULL) {//段为空?  
    next = seg->next;//下一个  
    count += tcp_seg_free(seg);//释放,  
    seg = next;//段指向下一个  
  }  
  return count;//返回计数  
}  
  
 
 
u8_t  
tcp_seg_free(struct tcp_seg *seg)  
{  
  u8_t count = 0;  
    
  if (seg != NULL) {//段为空?  
    if (seg->p != NULL) {//seg->p这段buffer包括了数据+TCP头,为空?  
      count = pbuf_free(seg->p);//释放  
#if TCP_DEBUG  
      seg->p = NULL;//置空  
#endif  
    }  
    memp_free(MEMP_TCP_SEG, seg);//释放seg段  
  }  
  return count;//返回释放数量  
}  
  
 
 
void  
tcp_setprio(struct tcp_pcb *pcb, u8_t prio)  
{  
  pcb->prio = prio;//设置新的优先级  
}  
#if TCP_QUEUE_OOSEQ  
  
  
  
struct tcp_seg *  
tcp_seg_copy(struct tcp_seg *seg)  
{  
  struct tcp_seg *cseg;  
  
  cseg = memp_malloc(MEMP_TCP_SEG);//分配空间  
  if (cseg == NULL) {//分配失败?  
    return NULL;返回  
  }  
  SMEMCPY((u8_t *)cseg, (const u8_t *)seg, sizeof(struct tcp_seg)); //copy一个段  
  pbuf_ref(cseg->p);//增加pbuf的引用计数  
  return cseg;  
}  
#endif  
  
#if LWIP_CALLBACK_API  
 
 
static err_t  
tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)  
{  
  arg = arg;  
  if (p != NULL) {//传入的pbuf为空?  
    pbuf_free(p);//释放  
  } else if (err == ERR_OK) {  
    return tcp_close(pcb);//关闭tcp  
  }  
  return ERR_OK;  
}  
#endif  
  
 
 
static void  
tcp_kill_prio(u8_t prio)  
{  
  struct tcp_pcb *pcb, *inactive;  
  u32_t inactivity;  
  u8_t mprio;  
  
  mprio = TCP_PRIO_MAX;//TCP最大的优先级  
    
   
   
  inactivity = 0;  
  inactive = NULL;  
  for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {//遍历激活列表  
    if (pcb->prio <= prio &&  
       pcb->prio <= mprio &&  
       (u32_t)(tcp_ticks - pcb->tmr) >= inactivity) {//对比优先级且看是否处在激活状态  
      inactivity = tcp_ticks - pcb->tmr;//计算静止时间  
      inactive = pcb;//非激活  
      mprio = pcb->prio;//获取优先级  
    }  
  }  
  if (inactive != NULL) {//为空?非空则说明找到了  
    LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB %p (%"S32_F")\n",  
           (void *)inactive, inactivity));  
    tcp_abort(inactive);//终止它  
  }        
}  
  
 
 
static void  
tcp_kill_timewait(void)  
{  
  struct tcp_pcb *pcb, *inactive;  
  u32_t inactivity;  
  
  inactivity = 0;  
  inactive = NULL;  
   
   
  for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {  
    if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) {//是否在静止状态?否  
      inactivity = tcp_ticks - pcb->tmr;//得到静止计时  
      inactive = pcb;//静止指针指向pcb  
    }  
  }  
  if (inactive != NULL) {//找到了?  
    LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB %p (%"S32_F")\n",  
           (void *)inactive, inactivity));  
    tcp_abort(inactive);//终止  
  }        
}  
  
 
 
struct tcp_pcb *  
tcp_alloc(u8_t prio)  
{  
  struct tcp_pcb *pcb;  
  u32_t iss;  
    
  pcb = memp_malloc(MEMP_TCP_PCB);//分配一个MEMP_TCP_PCB  
  if (pcb == NULL) {//分配成功?  
     
     
    LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest TIME-WAIT connection\n"));  
    tcp_kill_timewait();  
     
     
    pcb = memp_malloc(MEMP_TCP_PCB);  
    if (pcb == NULL) {  
       
       
      tcp_kill_prio(prio);  
       
       
      pcb = memp_malloc(MEMP_TCP_PCB);  
    }  
  }  
  if (pcb != NULL) {  
    memset(pcb, 0, sizeof(struct tcp_pcb));//初始化内存置0  
    pcb->prio = TCP_PRIO_NORMAL;//设置为普通优先级  
    pcb->snd_buf = TCP_SND_BUF;//设置TCP发送的空间为256  
    pcb->snd_queuelen = 0;//发送队列长度置0  
    pcb->rcv_wnd = TCP_WND;//TCP结构窗口  
    pcb->rcv_ann_wnd = TCP_WND;//TCP发布窗口  
    pcb->tos = 0;//服务类型  
    pcb->ttl = TCP_TTL;//默认存活时间  
     
     
    pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS;//设置pcb的mss  
    pcb->rto = 3000 / TCP_SLOW_INTERVAL;//设置重传超时  
    pcb->sa = 0;//  
    pcb->sv = 3000 / TCP_SLOW_INTERVAL;//  
    pcb->rtime = -1;//重传计时器  
    pcb->cwnd = 1;//拥挤避免  
    iss = tcp_next_iss();//计算新的连接的初始化队列数  
    pcb->snd_wl2 = iss;//最后的窗口更新序列和应答号  
    pcb->snd_nxt = iss;//下一个发送的心的序列号  
    pcb->lastack = iss;//最后的应答号  
    pcb->snd_lbb = iss;//下一个字节的进入buffer的序列数     
    pcb->tmr = tcp_ticks;//计时器  
  
    pcb->polltmr = 0;//池计时器  
  
#if LWIP_CALLBACK_API  
    pcb->recv = tcp_recv_null;//接收函数默认  
#endif    
      
     
     
    pcb->keep_idle  = TCP_KEEPIDLE_DEFAULT;  
      
#if LWIP_TCP_KEEPALIVE  
    pcb->keep_intvl = TCP_KEEPINTVL_DEFAULT;//初始化KEEPALIVE默认时间间隔  
    pcb->keep_cnt   = TCP_KEEPCNT_DEFAULT;//初始化KEEPALIVE计数  
#endif  
  
    pcb->keep_cnt_sent = 0;//发送计数置0  
  }  
  return pcb;//返回新生成的pcb  
}  
  
 
 
struct tcp_pcb *  
tcp_new(void)  
{  
  return tcp_alloc(TCP_PRIO_NORMAL);//分配一个新的pcb  
}  
  
  
  
void  
tcp_arg(struct tcp_pcb *pcb, void *arg)  
{    
  pcb->callback_arg = arg;//设置回调函数参数  
}  
#if LWIP_CALLBACK_API  
  
  
  
void  
tcp_recv(struct tcp_pcb *pcb,  
   err_t (* recv)(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err))  
{  
  pcb->recv = recv;//设置相应的接收回调函数  
}  
  
  
  
void  
tcp_sent(struct tcp_pcb *pcb,  
   err_t (* sent)(void *arg, struct tcp_pcb *tpcb, u16_t len))  
{  
  pcb->sent = sent;//设置相应的发送回调函数  
}  
  
  
 
void  
tcp_err(struct tcp_pcb *pcb,  
   void (* errf)(void *arg, err_t err))  
{  
  pcb->errf = errf;//设置致命错误回调函数  
}  
  
  
  
void  
tcp_accept(struct tcp_pcb *pcb,  
     err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err))  
{  
  pcb->accept = accept;//设置接受回调函数  
}  
#endif  
  
  
  
  
void  
tcp_poll(struct tcp_pcb *pcb,  
   err_t (* poll)(void *arg, struct tcp_pcb *tpcb), u8_t interval)  
{  
#if LWIP_CALLBACK_API  
  pcb->poll = poll;//设置回调函数  
#endif    
  pcb->pollinterval = interval;//设置时间间隔  
}  
  
 
 
void  
tcp_pcb_purge(struct tcp_pcb *pcb)  
{  
  if (pcb->state != CLOSED &&  
     pcb->state != TIME_WAIT &&  
     pcb->state != LISTEN) {//看状态都否CLOSED,TIME_WAIT,LISTEN?  
  
    LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge\n"));  
  
#if TCP_LISTEN_BACKLOG  
    if (pcb->state == SYN_RCVD) {//状态是否为SYN_RCVD  
       
       
      struct tcp_pcb_listen *lpcb;  
      LWIP_ASSERT("tcp_pcb_purge: pcb->state == SYN_RCVD but tcp_listen_pcbs is NULL",  
        tcp_listen_pcbs.listen_pcbs != NULL);  
      //遍历监听的pcb列表  
      for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {  
        if ((lpcb->local_port == pcb->local_port) &&  
            (ip_addr_isany(&lpcb->local_ip) ||  
             ip_addr_cmp(&pcb->local_ip, &lpcb->local_ip))) {  
             
             
            LWIP_ASSERT("tcp_pcb_purge: listen pcb does not have accepts pending",  
              lpcb->accepts_pending > 0);  
            lpcb->accepts_pending--;//接受挂起数减1  
            break;  
          }  
      }  
    }  
#endif  
  
  
    if (pcb->refused_data != NULL) {//拒绝数据为空?  
      LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->refused_data\n"));  
      pbuf_free(pcb->refused_data);//释放拒绝数据  
      pcb->refused_data = NULL;//把指针指向空  
    }  
    if (pcb->unsent != NULL) {//未发送全部数据  
      LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: not all data sent\n"));  
    }  
    if (pcb->unacked != NULL) {//未应答?  
      LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->unacked\n"));  
    }  
#if TCP_QUEUE_OOSEQ  
    if (pcb->ooseq != NULL) {//接收超出队列段序列  
      LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n"));  
    }  
  
     
     
    pcb->rtime = -1;  
  
    tcp_segs_free(pcb->ooseq);//释放接收超出队列段  
    pcb->ooseq = NULL;  
#endif  
    tcp_segs_free(pcb->unsent);//释放未发送段  
    tcp_segs_free(pcb->unacked);//释放为应答段  
    pcb->unacked = pcb->unsent = NULL;//置空  
  }  
}  
  
 
 
void  
tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb)  
{  
  TCP_RMV(pcblist, pcb);//移除pcb  
  tcp_pcb_purge(pcb);//清理pcb  
    
   
   
  if (pcb->state != TIME_WAIT &&  
     pcb->state != LISTEN &&  
     pcb->flags & TF_ACK_DELAY) {  
    pcb->flags |= TF_ACK_NOW;//标记为应答  
    tcp_output(pcb);//发送  
  }  
  
  if (pcb->state != LISTEN) {//如果不是监听状态  
    LWIP_ASSERT("unsent segments leaking", pcb->unsent == NULL);  
    LWIP_ASSERT("unacked segments leaking", pcb->unacked == NULL);  
#if TCP_QUEUE_OOSEQ  
    LWIP_ASSERT("ooseq segments leaking", pcb->ooseq == NULL);  
#endif  
  }  
  
  pcb->state = CLOSED;//pcb状态设为CLOSED  
  
  LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane());  
}  
  
 
 
u32_t  
tcp_next_iss(void)  
{  
  static u32_t iss = 6510;  
    
  iss += tcp_ticks;        
  return iss;  
}  
  
#if TCP_CALCULATE_EFF_SEND_MSS  
 
 
u16_t  
tcp_eff_send_mss(u16_t sendmss, struct ip_addr *addr)  
{  
  u16_t mss_s;  
  struct netif *outif;  
  
  outif = ip_route(addr);//从适当的网络接口中找到匹配的netif  
  if ((outif != NULL) && (outif->mtu != 0)) {//outif找到?最大的传送单元为0?  
    mss_s = outif->mtu - IP_HLEN - TCP_HLEN;//最大传送单元减去IP头和TCP头  
     
     
    sendmss = LWIP_MIN(sendmss, mss_s);//最小的发送段大小  
  }  
  return sendmss;//得到有效的段大小   
}  
#endif  
  
#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG  
 
 
void  
tcp_debug_print(struct tcp_hdr *tcphdr)  
{  
  LWIP_DEBUGF(TCP_DEBUG, ("TCP header:\n"));  
  LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));  
  LWIP_DEBUGF(TCP_DEBUG, ("|    %5"U16_F"      |    %5"U16_F"      | (src port, dest port)\n",  
         ntohs(tcphdr->src), ntohs(tcphdr->dest)));  
  LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));  
  LWIP_DEBUGF(TCP_DEBUG, ("|           0"U32_F"          | (seq no)\n",  
          ntohl(tcphdr->seqno)));  
  LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));  
  LWIP_DEBUGF(TCP_DEBUG, ("|           0"U32_F"          | (ack no)\n",  
         ntohl(tcphdr->ackno)));  
  LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));  
  LWIP_DEBUGF(TCP_DEBUG, ("| %2"U16_F" |   |%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"|     %5"U16_F"     | (hdrlen, flags (",  
       TCPH_HDRLEN(tcphdr),  
         TCPH_FLAGS(tcphdr) >> 5 & 1,  
         TCPH_FLAGS(tcphdr) >> 4 & 1,  
         TCPH_FLAGS(tcphdr) >> 3 & 1,  
         TCPH_FLAGS(tcphdr) >> 2 & 1,  
         TCPH_FLAGS(tcphdr) >> 1 & 1,  
         TCPH_FLAGS(tcphdr) & 1,  
         ntohs(tcphdr->wnd)));  
  tcp_debug_print_flags(TCPH_FLAGS(tcphdr));  
  LWIP_DEBUGF(TCP_DEBUG, ("), win)\n"));  
  LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));  
  LWIP_DEBUGF(TCP_DEBUG, ("|    0x"X16_F"     |     %5"U16_F"     | (chksum, urgp)\n",  
         ntohs(tcphdr->chksum), ntohs(tcphdr->urgp)));  
  LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));  
}  
  
 
 
void  
tcp_debug_print_state(enum tcp_state s)  
{  
  LWIP_DEBUGF(TCP_DEBUG, ("State: "));  
  switch (s) {  
  case CLOSED:  
    LWIP_DEBUGF(TCP_DEBUG, ("CLOSED\n"));  
    break;  
 case LISTEN:  
   LWIP_DEBUGF(TCP_DEBUG, ("LISTEN\n"));  
   break;  
  case SYN_SENT:  
    LWIP_DEBUGF(TCP_DEBUG, ("SYN_SENT\n"));  
    break;  
  case SYN_RCVD:  
    LWIP_DEBUGF(TCP_DEBUG, ("SYN_RCVD\n"));  
    break;  
  case ESTABLISHED:  
    LWIP_DEBUGF(TCP_DEBUG, ("ESTABLISHED\n"));  
    break;  
  case FIN_WAIT_1:  
    LWIP_DEBUGF(TCP_DEBUG, ("FIN_WAIT_1\n"));  
    break;  
  case FIN_WAIT_2:  
    LWIP_DEBUGF(TCP_DEBUG, ("FIN_WAIT_2\n"));  
    break;  
  case CLOSE_WAIT:  
    LWIP_DEBUGF(TCP_DEBUG, ("CLOSE_WAIT\n"));  
    break;  
  case CLOSING:  
    LWIP_DEBUGF(TCP_DEBUG, ("CLOSING\n"));  
    break;  
  case LAST_ACK:  
    LWIP_DEBUGF(TCP_DEBUG, ("LAST_ACK\n"));  
    break;  
  case TIME_WAIT:  
    LWIP_DEBUGF(TCP_DEBUG, ("TIME_WAIT\n"));  
   break;  
  }  
}  
  
 
 
void  
tcp_debug_print_flags(u8_t flags)  
{  
  if (flags & TCP_FIN) {  
    LWIP_DEBUGF(TCP_DEBUG, ("FIN "));  
  }  
  if (flags & TCP_SYN) {  
    LWIP_DEBUGF(TCP_DEBUG, ("SYN "));  
  }  
  if (flags & TCP_RST) {  
    LWIP_DEBUGF(TCP_DEBUG, ("RST "));  
  }  
  if (flags & TCP_PSH) {  
    LWIP_DEBUGF(TCP_DEBUG, ("PSH "));  
  }  
  if (flags & TCP_ACK) {  
    LWIP_DEBUGF(TCP_DEBUG, ("ACK "));  
  }  
  if (flags & TCP_URG) {  
    LWIP_DEBUGF(TCP_DEBUG, ("URG "));  
  }  
  if (flags & TCP_ECE) {  
    LWIP_DEBUGF(TCP_DEBUG, ("ECE "));  
  }  
  if (flags & TCP_CWR) {  
    LWIP_DEBUGF(TCP_DEBUG, ("CWR "));  
  }  
  LWIP_DEBUGF(TCP_DEBUG, ("\n"));  
}  
  
 
 
void  
tcp_debug_print_pcbs(void)  
{  
  struct tcp_pcb *pcb;  
  LWIP_DEBUGF(TCP_DEBUG, ("Active PCB states:\n"));  
  for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {  
    LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",  
                       pcb->local_port, pcb->remote_port,  
                       pcb->snd_nxt, pcb->rcv_nxt));  
    tcp_debug_print_state(pcb->state);  
  }      
  LWIP_DEBUGF(TCP_DEBUG, ("Listen PCB states:\n"));  
  for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) {  
    LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",  
                       pcb->local_port, pcb->remote_port,  
                       pcb->snd_nxt, pcb->rcv_nxt));  
    tcp_debug_print_state(pcb->state);  
  }      
  LWIP_DEBUGF(TCP_DEBUG, ("TIME-WAIT PCB states:\n"));  
  for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {  
    LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",  
                       pcb->local_port, pcb->remote_port,  
                       pcb->snd_nxt, pcb->rcv_nxt));  
    tcp_debug_print_state(pcb->state);  
  }      
}  
  
 
 
s16_t  
tcp_pcbs_sane(void)  
{  
  struct tcp_pcb *pcb;  
  for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {  
    LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != CLOSED", pcb->state != CLOSED);  
    LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != LISTEN", pcb->state != LISTEN);  
    LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);  
  }  
  for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {  
    LWIP_ASSERT("tcp_pcbs_sane: tw pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);  
  }  
  return 1;  
}  
#endif  
  
#endif

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有