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

📄 tcp.c

📁 最新rtlinux内核源码
💻 C
📖 第 1 页 / 共 3 页
字号:
    if(pcb->local_port == port) {      goto again;    }  }  return port;}/*-----------------------------------------------------------------------------------*//* * tcp_connect(): * * Connects to another host. The function given as the "connected" * argument will be called when the connection has been established. * *//*-----------------------------------------------------------------------------------*/err_ttcp_connect(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port,	    err_t (* connected)(void *arg, struct tcp_pcb *tpcb, err_t err)){  u32_t optdata;  err_t ret;  u32_t iss;  DEBUGF(TCP_DEBUG, ("tcp_connect to port %u\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;#if LWIP_CALLBACK_API    pcb->connected = connected;#endif /* LWIP_CALLBACK_API */    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){  struct tcp_pcb *pcb, *pcb2, *prev;  u32_t eff_wnd;  u8_t pcb_remove;      /* flag if a PCB should be removed */  err_t err;    err = ERR_OK;  ++tcp_ticks;    /* Steps through all of the active PCBs. */  prev = NULL;  pcb = tcp_active_pcbs;  if (pcb == NULL) DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n"));  while(pcb != NULL) {    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) {      ++pcb_remove;      DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n"));    }    else if(pcb->nrtx == TCP_MAXRTX) {      ++pcb_remove;      DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n"));    } else {      ++pcb->rtime;      if(pcb->unacked != NULL && pcb->rtime >= pcb->rto) {	/* Time for a retransmission. */        DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %u pcb->rto %u\n",                               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];	}	tcp_rexmit(pcb);	        /* 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_slowtmr: 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;        DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n"));      }    }    /* 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;      DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: dropping OOSEQ queued data\n"));    }#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;        DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n"));      }    }    /* 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) {	LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs);        prev->next = pcb->next;      } else {        /* This PCB was the first. */        LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb);        tcp_active_pcbs = pcb->next;      }      TCP_EVENT_ERR(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->polltmr = 0;        DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n"));	TCP_EVENT_POLL(pcb, err);	if(err == ERR_OK) {	  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) {    LWIP_ASSERT("tcp_slowtmr: 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) {	LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs);        prev->next = pcb->next;      } else {        /* This PCB was the first. */        LWIP_ASSERT("tcp_slowtmr: 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_fasttmr: 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_setprio(): * * Sets the priority of a connection. * *//*-----------------------------------------------------------------------------------*/voidtcp_setprio(struct tcp_pcb *pcb, u8_t prio){  pcb->prio = prio;}/*-----------------------------------------------------------------------------------*//* * 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;  }  memcpy((char *)cseg, (const char *)seg, sizeof(struct tcp_seg));   pbuf_ref(cseg->p);  return cseg;}/*-----------------------------------------------------------------------------------*/#if LWIP_CALLBACK_APIstatic err_ttcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err){  arg = arg;  if(p != NULL) {    pbuf_free(p);  } else if(err == ERR_OK) {    return tcp_close(pcb);  }  return ERR_OK;}#endif /* LWIP_CALLBACK_API *//*-----------------------------------------------------------------------------------*/static voidtcp_kill_prio(u8_t prio){  struct tcp_pcb *pcb, *inactive;  u32_t inactivity;  u8_t mprio;  mprio = TCP_PRIO_MAX;    /* We kill the oldest active connection that has lower priority than     prio. */  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) {    DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB 0x%p (%ld)\n",		       (void *)inactive, inactivity));    tcp_abort(inactive);  }      }/*-----------------------------------------------------------------------------------*/static voidtcp_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;    }  }  if(inactive != NULL) {    DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB 0x%p (%ld)\n",		       (void *)inactive, inactivity));    tcp_abort(inactive);

⌨️ 快捷键说明

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