⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcp.c

📁 lwip在ucos上的移植源码
💻 C
📖 第 1 页 / 共 3 页
字号:
  DEBUGF(TCP_DEBUG, ("tcp_connect to port %d\n", port));  if(ipaddr != NULL) {    pcb->remote_ip = *ipaddr;  } else {    return ERR_VAL;  }  pcb->remote_port = port;  if(pcb->local_port == 0) {    pcb->local_port = tcp_new_port();  }  iss = tcp_next_iss();  pcb->rcv_nxt = 0;  pcb->snd_nxt = iss;  pcb->lastack = iss - 1;  pcb->snd_lbb = iss - 1;  pcb->rcv_wnd = TCP_WND;  pcb->snd_wnd = TCP_WND;  pcb->mss = TCP_MSS;  pcb->cwnd = 1;  pcb->ssthresh = pcb->mss * 10;  pcb->state = SYN_SENT;  pcb->connected = connected;  TCP_REG(&tcp_active_pcbs, pcb);    /* Build an MSS option */  optdata = HTONL(((u32_t)2 << 24) | 		  ((u32_t)4 << 16) | 		  (((u32_t)pcb->mss / 256) << 8) |		  (pcb->mss & 255));  ret = tcp_enqueue(pcb, NULL, 0, TCP_SYN, 0, (u8_t *)&optdata, 4);  if(ret == ERR_OK) {     tcp_output(pcb);  }  return ret;} /*-----------------------------------------------------------------------------------*//* * tcp_slowtmr(): * * Called every 500 ms and implements the retransmission timer and the timer that * removes PCBs that have been in TIME-WAIT for enough time. It also increments * various timers such as the inactivity timer in each PCB. *//*-----------------------------------------------------------------------------------*/voidtcp_slowtmr(void){  static struct tcp_pcb *pcb, *pcb2, *prev;  static struct tcp_seg *seg, *useg;  static u32_t eff_wnd;  static u8_t pcb_remove;      /* flag if a PCB should be removed */  ++tcp_ticks;    /* Steps through all of the active PCBs. */  prev = NULL;  pcb = tcp_active_pcbs;  while(pcb != NULL) {    ASSERT("tcp_timer_coarse: active pcb->state != CLOSED", pcb->state != CLOSED);    ASSERT("tcp_timer_coarse: active pcb->state != LISTEN", pcb->state != LISTEN);    ASSERT("tcp_timer_coarse: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);    pcb_remove = 0;    if(pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) {      ++pcb_remove;    } else if(pcb->nrtx == TCP_MAXRTX) {      ++pcb_remove;    } else {      ++pcb->rtime;      seg = pcb->unacked;      if(seg != NULL && pcb->rtime >= pcb->rto) {                DEBUGF(TCP_RTO_DEBUG, ("tcp_timer_coarse: rtime %ld pcb->rto %d\n",                               tcp_ticks - pcb->rtime, pcb->rto));	/* Double retransmission time-out unless we are trying to           connect to somebody (i.e., we are in SYN_SENT). */	if(pcb->state != SYN_SENT) {	  pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx];	}        /* Move all other unacked segments to the unsent queue. */        if(seg->next != NULL) {          for(useg = seg->next; useg->next != NULL; useg = useg->next);          /* useg now points to the last segment on the unacked queue. */          useg->next = pcb->unsent;          pcb->unsent = seg->next;          seg->next = NULL;          pcb->snd_nxt = ntohl(pcb->unsent->tcphdr->seqno);        }	/* Do the actual retransmission. */        tcp_rexmit_seg(pcb, seg);        /* Reduce congestion window and ssthresh. */        eff_wnd = MIN(pcb->cwnd, pcb->snd_wnd);        pcb->ssthresh = eff_wnd >> 1;        if(pcb->ssthresh < pcb->mss) {          pcb->ssthresh = pcb->mss * 2;        }        pcb->cwnd = pcb->mss;        DEBUGF(TCP_CWND_DEBUG, ("tcp_rexmit_seg: cwnd %u ssthresh %u\n",                                pcb->cwnd, pcb->ssthresh));      }    }	      /* Check if this PCB has stayed too long in FIN-WAIT-2 */    if(pcb->state == FIN_WAIT_2) {      if((u32_t)(tcp_ticks - pcb->tmr) >	 TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) {        ++pcb_remove;      }    }    /* If this PCB has queued out of sequence data, but has been       inactive for too long, will drop the data (it will eventually       be retransmitted). */#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;    }#endif /* TCP_QUEUE_OOSEQ */    /* Check if this PCB has stayed too long in SYN-RCVD */    if(pcb->state == SYN_RCVD) {      if((u32_t)(tcp_ticks - pcb->tmr) >	 TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) {        ++pcb_remove;      }    }    /* If the PCB should be removed, do it. */    if(pcb_remove) {      tcp_pcb_purge(pcb);            /* Remove PCB from tcp_active_pcbs list. */      if(prev != NULL) {	ASSERT("tcp_timer_coarse: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs);        prev->next = pcb->next;      } else {        /* This PCB was the first. */        ASSERT("tcp_timer_coarse: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb);        tcp_active_pcbs = pcb->next;      }      if(pcb->errf != NULL) {	pcb->errf(pcb->callback_arg, ERR_ABRT);      }      pcb2 = pcb->next;      memp_free(MEMP_TCP_PCB, pcb);      pcb = pcb2;    } else {      /* We check if we should poll the connection. */      ++pcb->polltmr;      if(pcb->polltmr >= pcb->pollinterval &&	 pcb->poll != NULL) {	pcb->polltmr = 0;	pcb->poll(pcb->callback_arg, pcb);	tcp_output(pcb);      }            prev = pcb;      pcb = pcb->next;    }  }    /* Steps through all of the TIME-WAIT PCBs. */  prev = NULL;      pcb = tcp_tw_pcbs;  while(pcb != NULL) {    ASSERT("tcp_timer_coarse: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);    pcb_remove = 0;    /* Check if this PCB has stayed long enough in TIME-WAIT */    if((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {      ++pcb_remove;    }        /* If the PCB should be removed, do it. */    if(pcb_remove) {      tcp_pcb_purge(pcb);            /* Remove PCB from tcp_tw_pcbs list. */      if(prev != NULL) {	ASSERT("tcp_timer_coarse: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs);        prev->next = pcb->next;      } else {        /* This PCB was the first. */        ASSERT("tcp_timer_coarse: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb);        tcp_tw_pcbs = pcb->next;      }      pcb2 = pcb->next;      memp_free(MEMP_TCP_PCB, pcb);      pcb = pcb2;    } else {      prev = pcb;      pcb = pcb->next;    }  }}/*-----------------------------------------------------------------------------------*//* * tcp_fasttmr(): * * Is called every TCP_FINE_TIMEOUT (100 ms) and sends delayed ACKs. *//*-----------------------------------------------------------------------------------*/voidtcp_fasttmr(void){  struct tcp_pcb *pcb;  /* send delayed ACKs */    for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {    if(pcb->flags & TF_ACK_DELAY) {      DEBUGF(TCP_DEBUG, ("tcp_timer_fine: delayed ACK\n"));      tcp_ack_now(pcb);      pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);    }  }}/*-----------------------------------------------------------------------------------*//* * tcp_segs_free(): * * Deallocates a list of TCP segments (tcp_seg structures). * *//*-----------------------------------------------------------------------------------*/u8_ttcp_segs_free(struct tcp_seg *seg){  u8_t count = 0;  struct tcp_seg *next; again:    if(seg != NULL) {    next = seg->next;    count += tcp_seg_free(seg);    seg = next;    goto again;  }  return count;}/*-----------------------------------------------------------------------------------*//* * tcp_seg_free(): * * Frees a TCP segment. * *//*-----------------------------------------------------------------------------------*/u8_ttcp_seg_free(struct tcp_seg *seg){  u8_t count = 0;    if(seg != NULL) {    if(seg->p == NULL) {      memp_free(MEMP_TCP_SEG, seg);    } else {      count = pbuf_free(seg->p);#if TCP_DEBUG      seg->p = NULL;#endif /* TCP_DEBUG */      memp_free(MEMP_TCP_SEG, seg);    }  }  return count;}/*-----------------------------------------------------------------------------------*//* * tcp_seg_copy(): * * Returns a copy of the given TCP segment. * */ /*-----------------------------------------------------------------------------------*/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;  }  bcopy(seg, cseg, sizeof(struct tcp_seg));  pbuf_ref(cseg->p);  return cseg;}/*-----------------------------------------------------------------------------------*//* * tcp_new(): * * Creates a new TCP protocol control block but doesn't place it on * any of the TCP PCB lists. * *//*-----------------------------------------------------------------------------------*/struct tcp_pcb *tcp_new(void){  struct tcp_pcb *pcb;  u32_t iss;    pcb = memp_malloc2(MEMP_TCP_PCB);  if(pcb != NULL) {    bzero(pcb, sizeof(struct tcp_pcb));    pcb->snd_buf = TCP_SND_BUF;    pcb->snd_queuelen = 0;    pcb->rcv_wnd = TCP_WND;    pcb->mss = TCP_MSS;    pcb->rto = 3000 / TCP_SLOW_INTERVAL;    pcb->sa = 0;    pcb->sv = 3000 / TCP_SLOW_INTERVAL;    pcb->rtime = 0;    pcb->cwnd = 1;    iss = tcp_next_iss();    pcb->snd_wl2 = iss;    pcb->snd_nxt = iss;    pcb->snd_max = iss;    pcb->lastack = iss;    pcb->snd_lbb = iss;       pcb->tmr = tcp_ticks;    pcb->polltmr = 0;    return pcb;  }  return NULL;}/*-----------------------------------------------------------------------------------*//* * tcp_mem_reclaim(): * * Tries to free up TCP memory. This function is called from the memory manager * when memory is scarce. * *//*-----------------------------------------------------------------------------------*/#if MEM_RECLAIMstatic mem_size_ttcp_mem_reclaim(void *arg, mem_size_t size){  static struct tcp_pcb *pcb, *inactive;  static u32_t inactivity;  static mem_size_t reclaimed;  reclaimed = 0;  /* Kill the oldest active connection, hoping that there may be     memory associated with it. */  inactivity = 0;  inactive = NULL;  for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {    if((u32_t)(tcp_ticks - pcb->tmr) > inactivity) {      inactivity = tcp_ticks - pcb->tmr;      inactive = pcb;    }  }  if(inactive != NULL) {    DEBUGF(TCP_DEBUG, ("tcp_mem_reclaim: killing oldest PCB 0x%p (%ld)\n",		       inactive, inactivity));    tcp_abort(inactive);  }  return reclaimed;}#endif /* MEM_RECLAIM *//*-----------------------------------------------------------------------------------*//* * tcp_memp_reclaim(): * * Tries to free up TCP memory. This function is called from the * memory pool manager when memory is scarce. * */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -