找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3663|回复: 0
收起左侧

有时候看描述也是一件很幸福的事情!二并快乐者,呵呵!

[复制链接]
ID:82781 发表于 2015-6-13 15:59 | 显示全部楼层 |阅读模式


闲言少叙!直接代码的干活!
  1. const char *tcp_state_str[] = {
  2.   "CLOSED",     
  3.   "LISTEN",     
  4.   "SYN_SENT",   
  5.   "SYN_RCVD",   
  6.   "ESTABLISHED",
  7.   "FIN_WAIT_1",
  8.   "FIN_WAIT_2",
  9.   "CLOSE_WAIT",
  10.   "CLOSING",   
  11.   "LAST_ACK",   
  12.   "TIME_WAIT"  
  13. };
  14. /* Incremented every coarse grained timer shot (typically every 500 ms). */
  15. u32_t tcp_ticks;
  16. const u8_t tcp_backoff[13] =
  17.     { 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7};
  18. /* Times per slowtmr hits */
  19. const u8_t tcp_persist_backoff[7] = { 3, 6, 12, 24, 48, 96, 120 };
  20. /* The TCP PCB lists. */
  21. /** List of all TCP PCBs bound but not yet (connected || listening) */
  22. struct tcp_pcb *tcp_bound_pcbs;
  23. /** List of all TCP PCBs in LISTEN state */
  24. union tcp_listen_pcbs_t tcp_listen_pcbs;
  25. /** List of all TCP PCBs that are in a state in which
  26. * they accept or send data. */
  27. struct tcp_pcb *tcp_active_pcbs;
  28. /** List of all TCP PCBs in TIME-WAIT state */
  29. struct tcp_pcb *tcp_tw_pcbs;
  30. struct tcp_pcb *tcp_tmp_pcb;
  31. static u8_t tcp_timer;
  32. static u16_t tcp_new_port(void);
  33. /**
  34. * Called periodically to dispatch TCP timers.
  35. *
  36. */
  37. void
  38. tcp_tmr(void)
  39. {
  40.   /* Call tcp_fasttmr() every 250 ms */
  41.   tcp_fasttmr();
  42.   if (++tcp_timer & 1) {
  43.     /* Call tcp_tmr() every 500 ms, i.e., every other timer
  44.        tcp_tmr() is called. */
  45.     tcp_slowtmr();
  46.   }
  47. }
  48. /**
  49. * Closes the connection held by the PCB.
  50. *
  51. * Listening pcbs are freed and may not be referenced any more.
  52. * Connection pcbs are freed if not yet connected and may not be referenced
  53. * any more. If a connection is established (at least SYN received or in
  54. * a closing state), the connection is closed, and put in a closing state.
  55. * The pcb is then automatically freed in tcp_slowtmr(). It is therefore
  56. * unsafe to reference it.
  57. *
  58. * @param pcb the tcp_pcb to close
  59. * @return ERR_OK if connection has been closed
  60. *         another err_t if closing failed and pcb is not freed
  61. */
  62. err_t
  63. tcp_close(struct tcp_pcb *pcb)
  64. {
  65.   err_t err;
  66. #if TCP_DEBUG
  67.   LWIP_DEBUGF(TCP_DEBUG, ("tcp_close: closing in "));
  68.   tcp_debug_print_state(pcb->state);
  69. #endif /* TCP_DEBUG */
  70.   switch (pcb->state) {
  71.   case CLOSED:
  72.     /* Closing a pcb in the CLOSED state might seem erroneous,
  73.      * however, it is in this state once allocated and as yet unused
  74.      * and the user needs some way to free it should the need arise.
  75.      * Calling tcp_close() with a pcb that has already been closed, (i.e. twice)
  76.      * or for a pcb that has been used and then entered the CLOSED state
  77.      * is erroneous, but this should never happen as the pcb has in those cases
  78.      * been freed, and so any remaining handles are bogus. */
  79.     err = ERR_OK;
  80.     TCP_RMV(&tcp_bound_pcbs, pcb);
  81.     memp_free(MEMP_TCP_PCB, pcb);
  82.     pcb = NULL;
  83.     break;
  84.   case LISTEN:
  85.     err = ERR_OK;
  86.     tcp_pcb_remove((struct tcp_pcb **)&tcp_listen_pcbs.pcbs, pcb);
  87.     memp_free(MEMP_TCP_PCB_LISTEN, pcb);
  88.     pcb = NULL;
  89.     break;
  90.   case SYN_SENT:
  91.     err = ERR_OK;
  92.     tcp_pcb_remove(&tcp_active_pcbs, pcb);
  93.     memp_free(MEMP_TCP_PCB, pcb);
  94.     pcb = NULL;
  95.     snmp_inc_tcpattemptfails();
  96.     break;
  97.   case SYN_RCVD:
  98.     err = tcp_send_ctrl(pcb, TCP_FIN);
  99.     if (err == ERR_OK) {
  100.       snmp_inc_tcpattemptfails();
  101.       pcb->state = FIN_WAIT_1;
  102.     }
  103.     break;
  104.   case ESTABLISHED:
  105.     err = tcp_send_ctrl(pcb, TCP_FIN);
  106.     if (err == ERR_OK) {
  107.       snmp_inc_tcpestabresets();
  108.       pcb->state = FIN_WAIT_1;
  109.     }
  110.     break;
  111.   case CLOSE_WAIT:
  112.     err = tcp_send_ctrl(pcb, TCP_FIN);
  113.     if (err == ERR_OK) {
  114.       snmp_inc_tcpestabresets();
  115.       pcb->state = LAST_ACK;
  116.     }
  117.     break;
  118.   default:
  119.     /* Has already been closed, do nothing. */
  120.     err = ERR_OK;
  121.     pcb = NULL;
  122.     break;
  123.   }
  124.   if (pcb != NULL && err == ERR_OK) {
  125.     /* To ensure all data has been sent when tcp_close returns, we have
  126.        to make sure tcp_output doesn't fail.
  127.        Since we don't really have to ensure all data has been sent when tcp_close
  128.        returns (unsent data is sent from tcp timer functions, also), we don't care
  129.        for the return value of tcp_output for now. */
  130.     /* @todo: When implementing SO_LINGER, this must be changed somehow:
  131.        If SOF_LINGER is set, the data should be sent when tcp_close returns. */
  132.     tcp_output(pcb);
  133.   }
  134.   return err;
  135. }
  136. /**
  137. * Abandons a connection and optionally sends a RST to the remote
  138. * host.  Deletes the local protocol control block. This is done when
  139. * a connection is killed because of shortage of memory.
  140. *
  141. * @param pcb the tcp_pcb to abort
  142. * @param reset boolean to indicate whether a reset should be sent
  143. */
  144. void
  145. tcp_abandon(struct tcp_pcb *pcb, int reset)
  146. {
  147.   u32_t seqno, ackno;
  148.   u16_t remote_port, local_port;
  149.   struct ip_addr remote_ip, local_ip;
  150. #if LWIP_CALLBACK_API
  151.   void (* errf)(void *arg, err_t err);
  152. #endif /* LWIP_CALLBACK_API */
  153.   void *errf_arg;

  154.   /* Figure out on which TCP PCB list we are, and remove us. If we
  155.      are in an active state, call the receive function associated with
  156.      the PCB with a NULL argument, and send an RST to the remote end. */
  157.   if (pcb->state == TIME_WAIT) {
  158.     tcp_pcb_remove(&tcp_tw_pcbs, pcb);
  159.     memp_free(MEMP_TCP_PCB, pcb);
  160.   } else {
  161.     seqno = pcb->snd_nxt;
  162.     ackno = pcb->rcv_nxt;
  163.     ip_addr_set(&local_ip, &(pcb->local_ip));
  164.     ip_addr_set(&remote_ip, &(pcb->remote_ip));
  165.     local_port = pcb->local_port;
  166.     remote_port = pcb->remote_port;
  167. #if LWIP_CALLBACK_API
  168.     errf = pcb->errf;
  169. #endif /* LWIP_CALLBACK_API */
  170.     errf_arg = pcb->callback_arg;
  171.     tcp_pcb_remove(&tcp_active_pcbs, pcb);
  172.     if (pcb->unacked != NULL) {
  173.       tcp_segs_free(pcb->unacked);
  174.     }
  175.     if (pcb->unsent != NULL) {
  176.       tcp_segs_free(pcb->unsent);
  177.     }
  178. #if TCP_QUEUE_OOSEQ   
  179.     if (pcb->ooseq != NULL) {
  180.       tcp_segs_free(pcb->ooseq);
  181.     }
  182. #endif /* TCP_QUEUE_OOSEQ */
  183.     memp_free(MEMP_TCP_PCB, pcb);
  184.     TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT);
  185.     if (reset) {
  186.       LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abandon: sending RST\n"));
  187.       tcp_rst(seqno, ackno, &local_ip, &remote_ip, local_port, remote_port);
  188.     }
  189.   }
  190. }
  191. /**
  192. * Binds the connection to a local portnumber and IP address. If the
  193. * IP address is not given (i.e., ipaddr == NULL), the IP address of
  194. * the outgoing network interface is used instead.
  195. *
  196. * @param pcb the tcp_pcb to bind (no check is done whether this pcb is
  197. *        already bound!)
  198. * @param ipaddr the local ip address to bind to (use IP_ADDR_ANY to bind
  199. *        to any local address
  200. * @param port the local port to bind to
  201. * @return ERR_USE if the port is already in use
  202. *         ERR_OK if bound
  203. */
  204. err_t
  205. tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
  206. {
  207.   struct tcp_pcb *cpcb;
  208.   LWIP_ERROR("tcp_bind: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_ISCONN);
  209.   if (port == 0) {
  210.     port = tcp_new_port();
  211.   }
  212.   /* Check if the address already is in use. */
  213.   /* Check the listen pcbs. */
  214.   for(cpcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs;
  215.       cpcb != NULL; cpcb = cpcb->next) {
  216.     if (cpcb->local_port == port) {
  217.       if (ip_addr_isany(&(cpcb->local_ip)) ||
  218.           ip_addr_isany(ipaddr) ||
  219.           ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {
  220.         return ERR_USE;
  221.       }
  222.     }
  223.   }
  224.   /* Check the connected pcbs. */
  225.   for(cpcb = tcp_active_pcbs;
  226.       cpcb != NULL; cpcb = cpcb->next) {
  227.     if (cpcb->local_port == port) {
  228.       if (ip_addr_isany(&(cpcb->local_ip)) ||
  229.           ip_addr_isany(ipaddr) ||
  230.           ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {
  231.         return ERR_USE;
  232.       }
  233.     }
  234.   }
  235.   /* Check the bound, not yet connected pcbs. */
  236.   for(cpcb = tcp_bound_pcbs; cpcb != NULL; cpcb = cpcb->next) {
  237.     if (cpcb->local_port == port) {
  238.       if (ip_addr_isany(&(cpcb->local_ip)) ||
  239.           ip_addr_isany(ipaddr) ||
  240.           ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {
  241.         return ERR_USE;
  242.       }
  243.     }
  244.   }
  245.   /* @todo: until SO_REUSEADDR is implemented (see task #6995 on savannah),
  246.    * we have to check the pcbs in TIME-WAIT state, also: */
  247.   for(cpcb = tcp_tw_pcbs; cpcb != NULL; cpcb = cpcb->next) {
  248.     if (cpcb->local_port == port) {
  249.       if (ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {
  250.         return ERR_USE;
  251.       }
  252.     }
  253.   }
  254.   if (!ip_addr_isany(ipaddr)) {
  255.     pcb->local_ip = *ipaddr;
  256.   }
  257.   pcb->local_port = port;
  258.   TCP_REG(&tcp_bound_pcbs, pcb);
  259.   LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %"U16_F"\n", port));
  260.   return ERR_OK;
  261. }
  262. #if LWIP_CALLBACK_API
  263. /**
  264. * Default accept callback if no accept callback is specified by the user.
  265. */
  266. static err_t
  267. tcp_accept_null(void *arg, struct tcp_pcb *pcb, err_t err)
  268. {
  269.   LWIP_UNUSED_ARG(arg);
  270.   LWIP_UNUSED_ARG(pcb);
  271.   LWIP_UNUSED_ARG(err);
  272.   return ERR_ABRT;
  273. }
  274. #endif /* LWIP_CALLBACK_API */
  275. /**
  276. * Set the state of the connection to be LISTEN, which means that it
  277. * is able to accept incoming connections. The protocol control block
  278. * is reallocated in order to consume less memory. Setting the
  279. * connection to LISTEN is an irreversible process.
  280. *
  281. * @param pcb the original tcp_pcb
  282. * @param backlog the incoming connections queue limit
  283. * @return tcp_pcb used for listening, consumes less memory.
  284. *
  285. * @note The original tcp_pcb is freed. This function therefore has to be
  286. *       called like this:
  287. *             tpcb = tcp_listen(tpcb);
  288. */
  289. struct tcp_pcb *
  290. tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
  291. {
  292.   struct tcp_pcb_listen *lpcb;
  293.   LWIP_UNUSED_ARG(backlog);
  294.   LWIP_ERROR("tcp_listen: pcb already connected", pcb->state == CLOSED, return NULL);
  295.   /* already listening? */
  296.   if (pcb->state == LISTEN) {
  297.     return pcb;
  298.   }
  299.   lpcb = memp_malloc(MEMP_TCP_PCB_LISTEN);
  300.   if (lpcb == NULL) {
  301.     return NULL;
  302.   }
  303.   lpcb->callback_arg = pcb->callback_arg;
  304.   lpcb->local_port = pcb->local_port;
  305.   lpcb->state = LISTEN;
  306.   lpcb->so_options = pcb->so_options;
  307.   lpcb->so_options |= SOF_ACCEPTCONN;
  308.   lpcb->ttl = pcb->ttl;
  309.   lpcb->tos = pcb->tos;
  310.   ip_addr_set(&lpcb->local_ip, &pcb->local_ip);
  311.   TCP_RMV(&tcp_bound_pcbs, pcb);
  312.   memp_free(MEMP_TCP_PCB, pcb);
  313. #if LWIP_CALLBACK_API
  314.   lpcb->accept = tcp_accept_null;
  315. #endif /* LWIP_CALLBACK_API */
  316. #if TCP_LISTEN_BACKLOG
  317.   lpcb->accepts_pending = 0;
  318.   lpcb->backlog = (backlog ? backlog : 1);
  319. #endif /* TCP_LISTEN_BACKLOG */
  320.   TCP_REG(&tcp_listen_pcbs.listen_pcbs, lpcb);
  321.   return (struct tcp_pcb *)lpcb;
  322. }
  323. /**
  324. * Update the state that tracks the available window space to advertise.
  325. *
  326. * Returns how much extra window would be advertised if we sent an
  327. * update now.
  328. */
  329. u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb)
  330. {
  331.   u32_t new_right_edge = pcb->rcv_nxt + pcb->rcv_wnd;
  332.   if (TCP_SEQ_GEQ(new_right_edge, pcb->rcv_ann_right_edge + LWIP_MIN((TCP_WND / 2), pcb->mss))) {
  333.     /* we can advertise more window */
  334.     pcb->rcv_ann_wnd = pcb->rcv_wnd;
  335.     return new_right_edge - pcb->rcv_ann_right_edge;
  336.   } else {
  337.     if (TCP_SEQ_GT(pcb->rcv_nxt, pcb->rcv_ann_right_edge)) {
  338.       /* Can happen due to other end sending out of advertised window,
  339.        * but within actual available (but not yet advertised) window */
  340.       pcb->rcv_ann_wnd = 0;
  341.     } else {
  342.       /* keep the right edge of window constant */
  343.       pcb->rcv_ann_wnd = pcb->rcv_ann_right_edge - pcb->rcv_nxt;
  344.     }
  345.     return 0;
  346.   }
  347. }
  348. /**
  349. * This function should be called by the application when it has
  350. * processed the data. The purpose is to advertise a larger window
  351. * when the data has been processed.
  352. *
  353. * @param pcb the tcp_pcb for which data is read
  354. * @param len the amount of bytes that have been read by the application
  355. */
  356. void
  357. tcp_recved(struct tcp_pcb *pcb, u16_t len)
  358. {
  359.   int wnd_inflation;
  360.   LWIP_ASSERT("tcp_recved: len would wrap rcv_wnd\n",
  361.               len <= 0xffff - pcb->rcv_wnd );
  362.   pcb->rcv_wnd += len;
  363.   if (pcb->rcv_wnd > TCP_WND)
  364.     pcb->rcv_wnd = TCP_WND;
  365.   wnd_inflation = tcp_update_rcv_ann_wnd(pcb);
  366.   /* If the change in the right edge of window is significant (default
  367.    * watermark is TCP_WND/2), then send an explicit update now.
  368.    * Otherwise wait for a packet to be sent in the normal course of
  369.    * events (or more window to be available later) */
  370.   if (wnd_inflation >= TCP_WND_UPDATE_THRESHOLD)
  371.     tcp_ack_now(pcb);
  372.   LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: recveived %"U16_F" bytes, wnd %"U16_F" (%"U16_F").\n",
  373.          len, pcb->rcv_wnd, TCP_WND - pcb->rcv_wnd));
  374. }
  375. /**
  376. * A nastly hack featuring 'goto' statements that allocates a
  377. * new TCP local port.
  378. *
  379. * @return a new (free) local TCP port number
  380. */
  381. static u16_t
  382. tcp_new_port(void)
  383. {
  384.   struct tcp_pcb *pcb;
  385. #ifndef TCP_LOCAL_PORT_RANGE_START
  386. #define TCP_LOCAL_PORT_RANGE_START 4096
  387. #define TCP_LOCAL_PORT_RANGE_END   0x7fff
  388. #endif
  389.   static u16_t port = TCP_LOCAL_PORT_RANGE_START;

  390. again:
  391.   if (++port > TCP_LOCAL_PORT_RANGE_END) {
  392.     port = TCP_LOCAL_PORT_RANGE_START;
  393.   }

  394.   for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
  395.     if (pcb->local_port == port) {
  396.       goto again;
  397.     }
  398.   }
  399.   for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
  400.     if (pcb->local_port == port) {
  401.       goto again;
  402.     }
  403.   }
  404.   for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) {
  405.     if (pcb->local_port == port) {
  406.       goto again;
  407.     }
  408.   }
  409.   return port;
  410. }
  411. /**
  412. * Connects to another host. The function given as the "connected"
  413. * argument will be called when the connection has been established.
  414. *
  415. * @param pcb the tcp_pcb used to establish the connection
  416. * @param ipaddr the remote ip address to connect to
  417. * @param port the remote tcp port to connect to
  418. * @param connected callback function to call when connected (or on error)
  419. * @return ERR_VAL if invalid arguments are given
  420. *         ERR_OK if connect request has been sent
  421. *         other err_t values if connect request couldn't be sent
  422. */
  423. err_t
  424. tcp_connect(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port,
  425.       err_t (* connected)(void *arg, struct tcp_pcb *tpcb, err_t err))
  426. {
  427.   err_t ret;
  428.   u32_t iss;
  429.   LWIP_ERROR("tcp_connect: can only connected from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN);
  430.   LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port));
  431.   if (ipaddr != NULL) {
  432.     pcb->remote_ip = *ipaddr;
  433.   } else {
  434.     return ERR_VAL;
  435.   }
  436.   pcb->remote_port = port;
  437.   if (pcb->local_port == 0) {
  438.     pcb->local_port = tcp_new_port();
  439.   }
  440.   iss = tcp_next_iss();
  441.   pcb->rcv_nxt = 0;
  442.   pcb->snd_nxt = iss;
  443.   pcb->lastack = iss - 1;
  444.   pcb->snd_lbb = iss - 1;
  445.   pcb->rcv_wnd = TCP_WND;
  446.   pcb->rcv_ann_wnd = TCP_WND;
  447.   pcb->rcv_ann_right_edge = pcb->rcv_nxt;
  448.   pcb->snd_wnd = TCP_WND;
  449.   /* As initial send MSS, we use TCP_MSS but limit it to 536.
  450.      The send MSS is updated when an MSS option is received. */
  451.   pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS;
  452. #if TCP_CALCULATE_EFF_SEND_MSS
  453.   pcb->mss = tcp_eff_send_mss(pcb->mss, ipaddr);
  454. #endif /* TCP_CALCULATE_EFF_SEND_MSS */
  455.   pcb->cwnd = 1;
  456.   pcb->ssthresh = pcb->mss * 10;
  457.   pcb->state = SYN_SENT;
  458. #if LWIP_CALLBACK_API
  459.   pcb->connected = connected;
  460. #endif /* LWIP_CALLBACK_API */
  461.   TCP_RMV(&tcp_bound_pcbs, pcb);
  462.   TCP_REG(&tcp_active_pcbs, pcb);
  463.   snmp_inc_tcpactiveopens();

  464.   ret = tcp_enqueue(pcb, NULL, 0, TCP_SYN, 0, TF_SEG_OPTS_MSS
  465. #if LWIP_TCP_TIMESTAMPS
  466.                     | TF_SEG_OPTS_TS
  467. #endif
  468.                     );
  469.   if (ret == ERR_OK) {
  470.     tcp_output(pcb);
  471.   }
  472.   return ret;
  473. }
  474. /**
  475. * Called every 500 ms and implements the retransmission timer and the timer that
  476. * removes PCBs that have been in TIME-WAIT for enough time. It also increments
  477. * various timers such as the inactivity timer in each PCB.
  478. *
  479. * Automatically called from tcp_tmr().
  480. */
  481. void
  482. tcp_slowtmr(void)
  483. {
  484.   struct tcp_pcb *pcb, *pcb2, *prev;
  485.   u16_t eff_wnd;
  486.   u8_t pcb_remove;      /* flag if a PCB should be removed */
  487.   u8_t pcb_reset;       /* flag if a RST should be sent when removing */
  488.   err_t err;
  489.   err = ERR_OK;
  490.   ++tcp_ticks;
  491.   /* Steps through all of the active PCBs. */
  492.   prev = NULL;
  493.   pcb = tcp_active_pcbs;
  494.   if (pcb == NULL) {
  495.     LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n"));
  496.   }
  497.   while (pcb != NULL) {
  498.     LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb\n"));
  499.     LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED);
  500.     LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN);
  501.     LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT);
  502.     pcb_remove = 0;
  503.     pcb_reset = 0;
  504.     if (pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) {
  505.       ++pcb_remove;
  506.       LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n"));
  507.     }
  508.     else if (pcb->nrtx == TCP_MAXRTX) {
  509.       ++pcb_remove;
  510.       LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n"));
  511.     } else {
  512.       if (pcb->persist_backoff > 0) {
  513.         /* If snd_wnd is zero, use persist timer to send 1 byte probes
  514.          * instead of using the standard retransmission mechanism. */
  515.         pcb->persist_cnt++;
  516.         if (pcb->persist_cnt >= tcp_persist_backoff[pcb->persist_backoff-1]) {
  517.           pcb->persist_cnt = 0;
  518.           if (pcb->persist_backoff < sizeof(tcp_persist_backoff)) {
  519.             pcb->persist_backoff++;
  520.           }
  521.           tcp_zero_window_probe(pcb);
  522.         }
  523.       } else {
  524.         /* Increase the retransmission timer if it is running */
  525.         if(pcb->rtime >= 0)
  526.           ++pcb->rtime;
  527.         if (pcb->unacked != NULL && pcb->rtime >= pcb->rto) {
  528.           /* Time for a retransmission. */
  529.           LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %"S16_F
  530.                                       " pcb->rto %"S16_F"\n",
  531.                                       pcb->rtime, pcb->rto));
  532.           /* Double retransmission time-out unless we are trying to
  533.            * connect to somebody (i.e., we are in SYN_SENT). */
  534.           if (pcb->state != SYN_SENT) {
  535.             pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx];
  536.           }
  537.           /* Reset the retransmission timer. */
  538.           pcb->rtime = 0;
  539.           /* Reduce congestion window and ssthresh. */
  540.           eff_wnd = LWIP_MIN(pcb->cwnd, pcb->snd_wnd);
  541.           pcb->ssthresh = eff_wnd >> 1;
  542.           if (pcb->ssthresh < pcb->mss) {
  543.             pcb->ssthresh = pcb->mss * 2;
  544.           }
  545.           pcb->cwnd = pcb->mss;
  546.           LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: cwnd %"U16_F
  547.                                        " ssthresh %"U16_F"\n",
  548.                                        pcb->cwnd, pcb->ssthresh));

  549.           /* The following needs to be called AFTER cwnd is set to one
  550.              mss - STJ */
  551.           tcp_rexmit_rto(pcb);
  552.         }
  553.       }
  554.     }
  555.     /* Check if this PCB has stayed too long in FIN-WAIT-2 */
  556.     if (pcb->state == FIN_WAIT_2) {
  557.       if ((u32_t)(tcp_ticks - pcb->tmr) >
  558.           TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) {
  559.         ++pcb_remove;
  560.         LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n"));
  561.       }
  562.     }
  563.     /* Check if KEEPALIVE should be sent */
  564.     if((pcb->so_options & SOF_KEEPALIVE) &&
  565.        ((pcb->state == ESTABLISHED) ||
  566.         (pcb->state == CLOSE_WAIT))) {
  567. #if LWIP_TCP_KEEPALIVE
  568.       if((u32_t)(tcp_ticks - pcb->tmr) >
  569.          (pcb->keep_idle + (pcb->keep_cnt*pcb->keep_intvl))
  570.          / TCP_SLOW_INTERVAL)
  571. #else     
  572.       if((u32_t)(tcp_ticks - pcb->tmr) >
  573.          (pcb->keep_idle + TCP_MAXIDLE) / TCP_SLOW_INTERVAL)
  574. #endif /* LWIP_TCP_KEEPALIVE */
  575.       {
  576.         LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to %"U16_F".%"U16_F".%"U16_F".%"U16_F".\n",
  577.                                 ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
  578.                                 ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip)));
  579.       
  580.         ++pcb_remove;
  581.         ++pcb_reset;
  582.       }
  583. #if LWIP_TCP_KEEPALIVE
  584.       else if((u32_t)(tcp_ticks - pcb->tmr) >
  585.               (pcb->keep_idle + pcb->keep_cnt_sent * pcb->keep_intvl)
  586.               / TCP_SLOW_INTERVAL)
  587. #else
  588.       else if((u32_t)(tcp_ticks - pcb->tmr) >
  589.               (pcb->keep_idle + pcb->keep_cnt_sent * TCP_KEEPINTVL_DEFAULT)
  590.               / TCP_SLOW_INTERVAL)
  591. #endif /* LWIP_TCP_KEEPALIVE */
  592.       {
  593.         tcp_keepalive(pcb);
  594.         pcb->keep_cnt_sent++;
  595.       }
  596.     }
  597.     /* If this PCB has queued out of sequence data, but has been
  598.        inactive for too long, will drop the data (it will eventually
  599.        be retransmitted). */
  600. #if TCP_QUEUE_OOSEQ   
  601.     if (pcb->ooseq != NULL &&
  602.         (u32_t)tcp_ticks - pcb->tmr >= pcb->rto * TCP_OOSEQ_TIMEOUT) {
  603.       tcp_segs_free(pcb->ooseq);
  604.       pcb->ooseq = NULL;
  605.       LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: dropping OOSEQ queued data\n"));
  606.     }
  607. #endif /* TCP_QUEUE_OOSEQ */
  608.     /* Check if this PCB has stayed too long in SYN-RCVD */
  609.     if (pcb->state == SYN_RCVD) {
  610.       if ((u32_t)(tcp_ticks - pcb->tmr) >
  611.           TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) {
  612.         ++pcb_remove;
  613.         LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n"));
  614.       }
  615.     }
  616.     /* Check if this PCB has stayed too long in LAST-ACK */
  617.     if (pcb->state == LAST_ACK) {
  618.       if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {
  619.         ++pcb_remove;
  620.         LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in LAST-ACK\n"));
  621.       }
  622.     }
  623.     /* If the PCB should be removed, do it. */
  624.     if (pcb_remove) {
  625.       tcp_pcb_purge(pcb);     
  626.       /* Remove PCB from tcp_active_pcbs list. */
  627.       if (prev != NULL) {
  628.         LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs);
  629.         prev->next = pcb->next;
  630.       } else {
  631.         /* This PCB was the first. */
  632.         LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb);
  633.         tcp_active_pcbs = pcb->next;
  634.       }
  635.       TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_ABRT);
  636.       if (pcb_reset) {
  637.         tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip,
  638.           pcb->local_port, pcb->remote_port);
  639.       }
  640.       pcb2 = pcb->next;
  641.       memp_free(MEMP_TCP_PCB, pcb);
  642.       pcb = pcb2;
  643.     } else {
  644.       /* We check if we should poll the connection. */
  645.       ++pcb->polltmr;
  646.       if (pcb->polltmr >= pcb->pollinterval) {
  647.         pcb->polltmr = 0;
  648.         LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n"));
  649.         TCP_EVENT_POLL(pcb, err);
  650.         if (err == ERR_OK) {
  651.           tcp_output(pcb);
  652.         }
  653.       }
  654.      
  655.       prev = pcb;
  656.       pcb = pcb->next;
  657.     }
  658.   }

  659.   /* Steps through all of the TIME-WAIT PCBs. */
  660.   prev = NULL;   
  661.   pcb = tcp_tw_pcbs;
  662.   while (pcb != NULL) {
  663.     LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
  664.     pcb_remove = 0;
  665.     /* Check if this PCB has stayed long enough in TIME-WAIT */
  666.     if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {
  667.       ++pcb_remove;
  668.     }
  669.    

  670.     /* If the PCB should be removed, do it. */
  671.     if (pcb_remove) {
  672.       tcp_pcb_purge(pcb);     
  673.       /* Remove PCB from tcp_tw_pcbs list. */
  674.       if (prev != NULL) {
  675.         LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs);
  676.         prev->next = pcb->next;
  677.       } else {
  678.         /* This PCB was the first. */
  679.         LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb);
  680.         tcp_tw_pcbs = pcb->next;
  681.       }
  682.       pcb2 = pcb->next;
  683.       memp_free(MEMP_TCP_PCB, pcb);
  684.       pcb = pcb2;
  685.     } else {
  686.       prev = pcb;
  687.       pcb = pcb->next;
  688.     }
  689.   }
  690. }
  691. /**
  692. * Is called every TCP_FAST_INTERVAL (250 ms) and process data previously
  693. * "refused" by upper layer (application) and sends delayed ACKs.
  694. *
  695. * Automatically called from tcp_tmr().
  696. */
  697. void
  698. tcp_fasttmr(void)
  699. {
  700.   struct tcp_pcb *pcb;
  701.   for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
  702.     /* If there is data which was previously "refused" by upper layer */
  703.     if (pcb->refused_data != NULL) {
  704.       /* Notify again application with data previously received. */
  705.       err_t err;
  706.       LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_fasttmr: notify kept packet\n"));
  707.       TCP_EVENT_RECV(pcb, pcb->refused_data, ERR_OK, err);
  708.       if (err == ERR_OK) {
  709.         pcb->refused_data = NULL;
  710.       }
  711.     }
  712.     /* send delayed ACKs */
  713.     if (pcb->flags & TF_ACK_DELAY) {
  714.       LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n"));
  715.       tcp_ack_now(pcb);
  716.       pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
  717.     }
  718.   }
  719. }
  720. /**
  721. * Deallocates a list of TCP segments (tcp_seg structures).
  722. *
  723. * @param seg tcp_seg list of TCP segments to free
  724. * @return the number of pbufs that were deallocated
  725. */
  726. u8_t
  727. tcp_segs_free(struct tcp_seg *seg)
  728. {
  729.   u8_t count = 0;
  730.   struct tcp_seg *next;
  731.   while (seg != NULL) {
  732.     next = seg->next;
  733.     count += tcp_seg_free(seg);
  734.     seg = next;
  735.   }
  736.   return count;
  737. }
  738. /**
  739. * Frees a TCP segment (tcp_seg structure).
  740. *
  741. * @param seg single tcp_seg to free
  742. * @return the number of pbufs that were deallocated
  743. */
  744. u8_t
  745. tcp_seg_free(struct tcp_seg *seg)
  746. {
  747.   u8_t count = 0;

  748.   if (seg != NULL) {
  749.     if (seg->p != NULL) {
  750.       count = pbuf_free(seg->p);
  751. #if TCP_DEBUG
  752.       seg->p = NULL;
  753. #endif /* TCP_DEBUG */
  754.     }
  755.     memp_free(MEMP_TCP_SEG, seg);
  756.   }
  757.   return count;
  758. }
  759. /**
  760. * Sets the priority of a connection.
  761. *
  762. * @param pcb the tcp_pcb to manipulate
  763. * @param prio new priority
  764. */
  765. void
  766. tcp_setprio(struct tcp_pcb *pcb, u8_t prio)
  767. {
  768.   pcb->prio = prio;
  769. }
  770. #if TCP_QUEUE_OOSEQ
  771. /**
  772. * Returns a copy of the given TCP segment.
  773. * The pbuf and data are not copied, only the pointers
  774. *
  775. * @param seg the old tcp_seg
  776. * @return a copy of seg
  777. */
  778. struct tcp_seg *
  779. tcp_seg_copy(struct tcp_seg *seg)
  780. {
  781.   struct tcp_seg *cseg;
  782.   cseg = memp_malloc(MEMP_TCP_SEG);
  783.   if (cseg == NULL) {
  784.     return NULL;
  785.   }
  786.   SMEMCPY((u8_t *)cseg, (const u8_t *)seg, sizeof(struct tcp_seg));
  787.   pbuf_ref(cseg->p);
  788.   return cseg;
  789. }
  790. #endif
  791. #if LWIP_CALLBACK_API
  792. /**
  793. * Default receive callback that is called if the user didn't register
  794. * a recv callback for the pcb.
  795. */
  796. err_t
  797. tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
  798. {
  799.   LWIP_UNUSED_ARG(arg);
  800.   if (p != NULL) {
  801.     tcp_recved(pcb, p->tot_len);
  802.     pbuf_free(p);
  803.   } else if (err == ERR_OK) {
  804.     return tcp_close(pcb);
  805.   }
  806.   return ERR_OK;
  807. }
  808. #endif /* LWIP_CALLBACK_API */
  809. /**
  810. * Kills the oldest active connection that has lower priority than prio.
  811. *
  812. * @param prio minimum priority
  813. */
  814. static void
  815. tcp_kill_prio(u8_t prio)
  816. {
  817.   struct tcp_pcb *pcb, *inactive;
  818.   u32_t inactivity;
  819.   u8_t mprio;

  820.   mprio = TCP_PRIO_MAX;

  821.   /* We kill the oldest active connection that has lower priority than prio. */
  822.   inactivity = 0;
  823.   inactive = NULL;
  824.   for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
  825.     if (pcb->prio <= prio &&
  826.        pcb->prio <= mprio &&
  827.        (u32_t)(tcp_ticks - pcb->tmr) >= inactivity) {
  828.       inactivity = tcp_ticks - pcb->tmr;
  829.       inactive = pcb;
  830.       mprio = pcb->prio;
  831.     }
  832.   }
  833.   if (inactive != NULL) {
  834.     LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB %p (%"S32_F")\n",
  835.            (void *)inactive, inactivity));
  836.     tcp_abort(inactive);
  837.   }     
  838. }
  839. /**
  840. * Kills the oldest connection that is in TIME_WAIT state.
  841. * Called from tcp_alloc() if no more connections are available.
  842. */
  843. static void
  844. tcp_kill_timewait(void)
  845. {
  846.   struct tcp_pcb *pcb, *inactive;
  847.   u32_t inactivity;
  848.   inactivity = 0;
  849.   inactive = NULL;
  850.   /* Go through the list of TIME_WAIT pcbs and get the oldest pcb. */
  851.   for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
  852.     if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) {
  853.       inactivity = tcp_ticks - pcb->tmr;
  854.       inactive = pcb;
  855.     }
  856.   }
  857.   if (inactive != NULL) {
  858.     LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB %p (%"S32_F")\n",
  859.            (void *)inactive, inactivity));
  860.     tcp_abort(inactive);
  861.   }     
  862. }
  863. /**
  864. * Allocate a new tcp_pcb structure.
  865. *
  866. * @param prio priority for the new pcb
  867. * @return a new tcp_pcb that initially is in state CLOSED
  868. */
  869. struct tcp_pcb *
  870. tcp_alloc(u8_t prio)
  871. {
  872.   struct tcp_pcb *pcb;
  873.   u32_t iss;

  874.   pcb = memp_malloc(MEMP_TCP_PCB);
  875.   if (pcb == NULL) {
  876.     /* Try killing oldest connection in TIME-WAIT. */
  877.     LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest TIME-WAIT connection\n"));
  878.     tcp_kill_timewait();
  879.     /* Try to allocate a tcp_pcb again. */
  880.     pcb = memp_malloc(MEMP_TCP_PCB);
  881.     if (pcb == NULL) {
  882.       /* Try killing active connections with lower priority than the new one. */
  883.       LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing connection with prio lower than %d\n", prio));
  884.       tcp_kill_prio(prio);
  885.       /* Try to allocate a tcp_pcb again. */
  886.       pcb = memp_malloc(MEMP_TCP_PCB);
  887.       if (pcb != NULL) {
  888.         /* adjust err stats: memp_malloc failed twice before */
  889.         MEMP_STATS_DEC(err, MEMP_TCP_PCB);
  890.       }
  891.     }
  892.     if (pcb != NULL) {
  893.       /* adjust err stats: timewait PCB was freed above */
  894.       MEMP_STATS_DEC(err, MEMP_TCP_PCB);
  895.     }
  896.   }
  897.   if (pcb != NULL) {
  898.     memset(pcb, 0, sizeof(struct tcp_pcb));
  899.     pcb->prio = TCP_PRIO_NORMAL;
  900.     pcb->snd_buf = TCP_SND_BUF;
  901.     pcb->snd_queuelen = 0;
  902.     pcb->rcv_wnd = TCP_WND;
  903.     pcb->rcv_ann_wnd = TCP_WND;
  904.     pcb->tos = 0;
  905.     pcb->ttl = TCP_TTL;
  906.     /* As initial send MSS, we use TCP_MSS but limit it to 536.
  907.        The send MSS is updated when an MSS option is received. */
  908.     pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS;
  909.     pcb->rto = 3000 / TCP_SLOW_INTERVAL;
  910.     pcb->sa = 0;
  911.     pcb->sv = 3000 / TCP_SLOW_INTERVAL;
  912.     pcb->rtime = -1;
  913.     pcb->cwnd = 1;
  914.     iss = tcp_next_iss();
  915.     pcb->snd_wl2 = iss;
  916.     pcb->snd_nxt = iss;
  917.     pcb->lastack = iss;
  918.     pcb->snd_lbb = iss;  
  919.     pcb->tmr = tcp_ticks;
  920.     pcb->polltmr = 0;
  921. #if LWIP_CALLBACK_API
  922.     pcb->recv = tcp_recv_null;
  923. #endif /* LWIP_CALLBACK_API */
  924.    
  925.     /* Init KEEPALIVE timer */
  926.     pcb->keep_idle  = TCP_KEEPIDLE_DEFAULT;
  927.    
  928. #if LWIP_TCP_KEEPALIVE
  929.     pcb->keep_intvl = TCP_KEEPINTVL_DEFAULT;
  930.     pcb->keep_cnt   = TCP_KEEPCNT_DEFAULT;
  931. #endif /* LWIP_TCP_KEEPALIVE */
  932.     pcb->keep_cnt_sent = 0;
  933.   }
  934.   return pcb;
  935. }
  936. /**
  937. * Creates a new TCP protocol control block but doesn't place it on
  938. * any of the TCP PCB lists.
  939. * The pcb is not put on any list until binding using tcp_bind().
  940. *
  941. * @internal: Maybe there should be a idle TCP PCB list where these
  942. * PCBs are put on. Port reservation using tcp_bind() is implemented but
  943. * allocated pcbs that are not bound can't be killed automatically if wanting
  944. * to allocate a pcb with higher prio (@see tcp_kill_prio())
  945. *
  946. * @return a new tcp_pcb that initially is in state CLOSED
  947. */
  948. struct tcp_pcb *
  949. tcp_new(void)
  950. {
  951.   return tcp_alloc(TCP_PRIO_NORMAL);
  952. }
  953. /**
  954. * Used to specify the argument that should be passed callback
  955. * functions.
  956. *
  957. * @param pcb tcp_pcb to set the callback argument
  958. * @param arg void pointer argument to pass to callback functions
  959. */
  960. void
  961. tcp_arg(struct tcp_pcb *pcb, void *arg)
  962. {
  963.   pcb->callback_arg = arg;
  964. }
  965. #if LWIP_CALLBACK_API
  966. /**
  967. * Used to specify the function that should be called when a TCP
  968. * connection receives data.
  969. *
  970. * @param pcb tcp_pcb to set the recv callback
  971. * @param recv callback function to call for this pcb when data is received
  972. */
  973. void
  974. tcp_recv(struct tcp_pcb *pcb,
  975.    err_t (* recv)(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err))
  976. {
  977.   pcb->recv = recv;
  978. }
  979. /**
  980. * Used to specify the function that should be called when TCP data
  981. * has been successfully delivered to the remote host.
  982. *
  983. * @param pcb tcp_pcb to set the sent callback
  984. * @param sent callback function to call for this pcb when data is successfully sent
  985. */
  986. void
  987. tcp_sent(struct tcp_pcb *pcb,
  988.    err_t (* sent)(void *arg, struct tcp_pcb *tpcb, u16_t len))
  989. {
  990.   pcb->sent = sent;
  991. }
  992. /**
  993. * Used to specify the function that should be called when a fatal error
  994. * has occured on the connection.
  995. *
  996. * @param pcb tcp_pcb to set the err callback
  997. * @param errf callback function to call for this pcb when a fatal error
  998. *        has occured on the connection
  999. */
  1000. void
  1001. tcp_err(struct tcp_pcb *pcb,
  1002.    void (* errf)(void *arg, err_t err))
  1003. {
  1004.   pcb->errf = errf;
  1005. }
  1006. /**
  1007. * Used for specifying the function that should be called when a
  1008. * LISTENing connection has been connected to another host.
  1009. *
  1010. * @param pcb tcp_pcb to set the accept callback
  1011. * @param accept callback function to call for this pcb when LISTENing
  1012. *        connection has been connected to another host
  1013. */
  1014. void
  1015. tcp_accept(struct tcp_pcb *pcb,
  1016.      err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err))
  1017. {
  1018.   pcb->accept = accept;
  1019. }
  1020. #endif /* LWIP_CALLBACK_API */

  1021. /**
  1022. * Used to specify the function that should be called periodically
  1023. * from TCP. The interval is specified in terms of the TCP coarse
  1024. * timer interval, which is called twice a second.
  1025. *
  1026. */
  1027. void
  1028. tcp_poll(struct tcp_pcb *pcb,
  1029.    err_t (* poll)(void *arg, struct tcp_pcb *tpcb), u8_t interval)
  1030. {
  1031. #if LWIP_CALLBACK_API
  1032.   pcb->poll = poll;
  1033. #endif /* LWIP_CALLBACK_API */
  1034.   pcb->pollinterval = interval;
  1035. }
  1036. /**
  1037. * Purges a TCP PCB. Removes any buffered data and frees the buffer memory
  1038. * (pcb->ooseq, pcb->unsent and pcb->unacked are freed).
  1039. *
  1040. * @param pcb tcp_pcb to purge. The pcb itself is not deallocated!
  1041. */
  1042. void
  1043. tcp_pcb_purge(struct tcp_pcb *pcb)
  1044. {
  1045.   if (pcb->state != CLOSED &&
  1046.      pcb->state != TIME_WAIT &&
  1047.      pcb->state != LISTEN) {
  1048.     LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge\n"));
  1049. #if TCP_LISTEN_BACKLOG
  1050.     if (pcb->state == SYN_RCVD) {
  1051.       /* Need to find the corresponding listen_pcb and decrease its accepts_pending */
  1052.       struct tcp_pcb_listen *lpcb;
  1053.       LWIP_ASSERT("tcp_pcb_purge: pcb->state == SYN_RCVD but tcp_listen_pcbs is NULL",
  1054.         tcp_listen_pcbs.listen_pcbs != NULL);
  1055.       for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
  1056.         if ((lpcb->local_port == pcb->local_port) &&
  1057.             (ip_addr_isany(&lpcb->local_ip) ||
  1058.              ip_addr_cmp(&pcb->local_ip, &lpcb->local_ip))) {
  1059.             /* port and address of the listen pcb match the timed-out pcb */
  1060.             LWIP_ASSERT("tcp_pcb_purge: listen pcb does not have accepts pending",
  1061.               lpcb->accepts_pending > 0);
  1062.             lpcb->accepts_pending--;
  1063.             break;
  1064.           }
  1065.       }
  1066.     }
  1067. #endif /* TCP_LISTEN_BACKLOG */

  1068.     if (pcb->refused_data != NULL) {
  1069.       LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->refused_data\n"));
  1070.       pbuf_free(pcb->refused_data);
  1071.       pcb->refused_data = NULL;
  1072.     }
  1073.     if (pcb->unsent != NULL) {
  1074.       LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: not all data sent\n"));
  1075.     }
  1076.     if (pcb->unacked != NULL) {
  1077.       LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->unacked\n"));
  1078.     }
  1079. #if TCP_QUEUE_OOSEQ /* LW */
  1080.     if (pcb->ooseq != NULL) {
  1081.       LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n"));
  1082.     }
  1083.     /* Stop the retransmission timer as it will expect data on unacked
  1084.        queue if it fires */
  1085.     pcb->rtime = -1;
  1086.     tcp_segs_free(pcb->ooseq);
  1087.     pcb->ooseq = NULL;
  1088. #endif /* TCP_QUEUE_OOSEQ */
  1089.     tcp_segs_free(pcb->unsent);
  1090.     tcp_segs_free(pcb->unacked);
  1091.     pcb->unacked = pcb->unsent = NULL;
  1092.   }
  1093. }
  1094. /**
  1095. * Purges the PCB and removes it from a PCB list. Any delayed ACKs are sent first.
  1096. *
  1097. * @param pcblist PCB list to purge.
  1098. * @param pcb tcp_pcb to purge. The pcb itself is NOT deallocated!
  1099. */
  1100. void
  1101. tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb)
  1102. {
  1103.   TCP_RMV(pcblist, pcb);
  1104.   tcp_pcb_purge(pcb);

  1105.   /* if there is an outstanding delayed ACKs, send it */
  1106.   if (pcb->state != TIME_WAIT &&
  1107.      pcb->state != LISTEN &&
  1108.      pcb->flags & TF_ACK_DELAY) {
  1109.     pcb->flags |= TF_ACK_NOW;
  1110.     tcp_output(pcb);
  1111.   }
  1112.   if (pcb->state != LISTEN) {
  1113.     LWIP_ASSERT("unsent segments leaking", pcb->unsent == NULL);
  1114.     LWIP_ASSERT("unacked segments leaking", pcb->unacked == NULL);
  1115. #if TCP_QUEUE_OOSEQ
  1116.     LWIP_ASSERT("ooseq segments leaking", pcb->ooseq == NULL);
  1117. #endif /* TCP_QUEUE_OOSEQ */
  1118.   }
  1119.   pcb->state = CLOSED;
  1120.   LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane());
  1121. }
  1122. /**
  1123. * Calculates a new initial sequence number for new connections.
  1124. //calculate ['k?lkjuleit]
  1125. vt.
  1126. 1. 计算;核算:
  1127. * @return u32_t pseudo random sequence number
  1128. */
  1129. u32_t
  1130. tcp_next_iss(void)
  1131. {
  1132.   static u32_t iss = 6510;

  1133.   iss += tcp_ticks;       /* XXX */
  1134.   return iss;
  1135. }
  1136. #if TCP_CALCULATE_EFF_SEND_MSS
  1137. /**
  1138. * Calcluates the effective send mss that can be used for a specific IP address
  1139. * by using ip_route to determin the netif used to send to the address and
  1140. * calculating the minimum of TCP_MSS and that netif's mtu (if set).
  1141. */
  1142. u16_t
  1143. tcp_eff_send_mss(u16_t sendmss, struct ip_addr *addr)
  1144. {
  1145.   u16_t mss_s;
  1146.   struct netif *outif;
  1147.   outif = ip_route(addr);
  1148.   if ((outif != NULL) && (outif->mtu != 0)) {
  1149.     mss_s = outif->mtu - IP_HLEN - TCP_HLEN;
  1150.     /* RFC 1122, chap 4.2.2.6:
  1151.      * Eff.snd.MSS = min(SendMSS+20, MMS_S) - TCPhdrsize - IPoptionsize
  1152.      * We correct for TCP options in tcp_enqueue(), and don't support
  1153.      * IP options
  1154.      */
  1155.     sendmss = LWIP_MIN(sendmss, mss_s);
  1156.   }
  1157.   return sendmss;
  1158. }
  1159. #endif /* TCP_CALCULATE_EFF_SEND_MSS */
  1160. const char*
  1161. tcp_debug_state_str(enum tcp_state s)
  1162. {
  1163.   return tcp_state_str[s];
  1164. }
  1165. #if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG
  1166. /**
  1167. * Print a tcp header for debugging purposes.
  1168. *
  1169. * @param tcphdr pointer to a struct tcp_hdr
  1170. */
  1171. void
  1172. tcp_debug_print(struct tcp_hdr *tcphdr)
  1173. {
  1174.   LWIP_DEBUGF(TCP_DEBUG, ("TCP header:\n"));
  1175.   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
  1176.   LWIP_DEBUGF(TCP_DEBUG, ("|    %5"U16_F"      |    %5"U16_F"      | (src port, dest port)\n",
  1177.          ntohs(tcphdr->src), ntohs(tcphdr->dest)));
  1178.   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
  1179.   LWIP_DEBUGF(TCP_DEBUG, ("|           %010"U32_F"          | (seq no)\n",
  1180.           ntohl(tcphdr->seqno)));
  1181.   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
  1182.   LWIP_DEBUGF(TCP_DEBUG, ("|           %010"U32_F"          | (ack no)\n",
  1183.          ntohl(tcphdr->ackno)));
  1184.   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
  1185.   LWIP_DEBUGF(TCP_DEBUG, ("| %2"U16_F" |   |%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"|     %5"U16_F"     | (hdrlen, flags (",
  1186.        TCPH_HDRLEN(tcphdr),
  1187.          TCPH_FLAGS(tcphdr) >> 5 & 1,
  1188.          TCPH_FLAGS(tcphdr) >> 4 & 1,
  1189.          TCPH_FLAGS(tcphdr) >> 3 & 1,
  1190.          TCPH_FLAGS(tcphdr) >> 2 & 1,
  1191.          TCPH_FLAGS(tcphdr) >> 1 & 1,
  1192.          TCPH_FLAGS(tcphdr) & 1,
  1193.          ntohs(tcphdr->wnd)));
  1194.   tcp_debug_print_flags(TCPH_FLAGS(tcphdr));
  1195.   LWIP_DEBUGF(TCP_DEBUG, ("), win)\n"));
  1196.   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
  1197.   LWIP_DEBUGF(TCP_DEBUG, ("|    0x%04"X16_F"     |     %5"U16_F"     | (chksum, urgp)\n",
  1198.          ntohs(tcphdr->chksum), ntohs(tcphdr->urgp)));
  1199.   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
  1200. }
  1201. /**
  1202. * Print a tcp state for debugging purposes.
  1203. *
  1204. * @param s enum tcp_state to print
  1205. */
  1206. void
  1207. tcp_debug_print_state(enum tcp_state s)
  1208. {
  1209.   LWIP_DEBUGF(TCP_DEBUG, ("State: %s\n", tcp_state_str[s]));
  1210. }
  1211. /**
  1212. * Print tcp flags for debugging purposes.
  1213. *
  1214. * @param flags tcp flags, all active flags are printed
  1215. */
  1216. void
  1217. tcp_debug_print_flags(u8_t flags)
  1218. {
  1219.   if (flags & TCP_FIN) {
  1220.     LWIP_DEBUGF(TCP_DEBUG, ("FIN "));
  1221.   }
  1222.   if (flags & TCP_SYN) {
  1223.     LWIP_DEBUGF(TCP_DEBUG, ("SYN "));
  1224.   }
  1225.   if (flags & TCP_RST) {
  1226.     LWIP_DEBUGF(TCP_DEBUG, ("RST "));
  1227.   }
  1228.   if (flags & TCP_PSH) {
  1229.     LWIP_DEBUGF(TCP_DEBUG, ("PSH "));
  1230.   }
  1231.   if (flags & TCP_ACK) {
  1232.     LWIP_DEBUGF(TCP_DEBUG, ("ACK "));
  1233.   }
  1234.   if (flags & TCP_URG) {
  1235.     LWIP_DEBUGF(TCP_DEBUG, ("URG "));
  1236.   }
  1237.   if (flags & TCP_ECE) {
  1238.     LWIP_DEBUGF(TCP_DEBUG, ("ECE "));
  1239.   }
  1240.   if (flags & TCP_CWR) {
  1241.     LWIP_DEBUGF(TCP_DEBUG, ("CWR "));
  1242.   }
  1243.   LWIP_DEBUGF(TCP_DEBUG, ("\n"));
  1244. }
  1245. /**
  1246. * Print all tcp_pcbs in every list for debugging purposes.
  1247. */
  1248. void
  1249. tcp_debug_print_pcbs(void)
  1250. {
  1251.   struct tcp_pcb *pcb;
  1252.   LWIP_DEBUGF(TCP_DEBUG, ("Active PCB states:\n"));
  1253.   for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
  1254.     LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
  1255.                        pcb->local_port, pcb->remote_port,
  1256.                        pcb->snd_nxt, pcb->rcv_nxt));
  1257.     tcp_debug_print_state(pcb->state);
  1258.   }   
  1259.   LWIP_DEBUGF(TCP_DEBUG, ("Listen PCB states:\n"));
  1260.   for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) {
  1261.     LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
  1262.                        pcb->local_port, pcb->remote_port,
  1263.                        pcb->snd_nxt, pcb->rcv_nxt));
  1264.     tcp_debug_print_state(pcb->state);
  1265.   }   
  1266.   LWIP_DEBUGF(TCP_DEBUG, ("TIME-WAIT PCB states:\n"));
  1267.   for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
  1268.     LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
  1269.                        pcb->local_port, pcb->remote_port,
  1270.                        pcb->snd_nxt, pcb->rcv_nxt));
  1271.     tcp_debug_print_state(pcb->state);
  1272.   }   
  1273. }
  1274. /**
  1275. * Check state consistency of the tcp_pcb lists.
  1276. */
  1277. s16_t
  1278. tcp_pcbs_sane(void)
  1279. {
  1280.   struct tcp_pcb *pcb;
  1281.   for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
  1282.     LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != CLOSED", pcb->state != CLOSED);
  1283.     LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != LISTEN", pcb->state != LISTEN);
  1284.     LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
  1285.   }
  1286.   for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
  1287.     LWIP_ASSERT("tcp_pcbs_sane: tw pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
  1288.   }
  1289.   return 1;
  1290. }
  1291. #endif /* TCP_DEBUG */
  1292. #endif /* LWIP_TCP */
复制代码





回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表