A version of LWIP, provided for backwards compatibility.

Dependents:   AA_DemoBoard DemoBoard HelloServerDemo DemoBoard_RangeIndicator ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers tcp.c Source File

tcp.c

Go to the documentation of this file.
00001 /**
00002  * @file
00003  * Transmission Control Protocol for IP
00004  *
00005  * This file contains common functions for the TCP implementation, such as functinos
00006  * for manipulating the data structures and the TCP timer functions. TCP functions
00007  * related to input and output is found in tcp_in.c and tcp_out.c respectively.
00008  *
00009  */
00010 
00011 /*
00012  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
00013  * All rights reserved. 
00014  * 
00015  * Redistribution and use in source and binary forms, with or without modification, 
00016  * are permitted provided that the following conditions are met:
00017  *
00018  * 1. Redistributions of source code must retain the above copyright notice,
00019  *    this list of conditions and the following disclaimer.
00020  * 2. Redistributions in binary form must reproduce the above copyright notice,
00021  *    this list of conditions and the following disclaimer in the documentation
00022  *    and/or other materials provided with the distribution.
00023  * 3. The name of the author may not be used to endorse or promote products
00024  *    derived from this software without specific prior written permission. 
00025  *
00026  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
00027  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
00028  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
00029  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
00030  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
00031  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00032  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
00033  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
00034  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
00035  * OF SUCH DAMAGE.
00036  *
00037  * This file is part of the lwIP TCP/IP stack.
00038  * 
00039  * Author: Adam Dunkels <adam@sics.se>
00040  *
00041  */
00042 
00043 #include "lwip/opt.h"
00044 
00045 #if LWIP_TCP /* don't build if not configured for use in lwipopts.h */
00046 
00047 #include "lwip/def.h"
00048 #include "lwip/mem.h"
00049 #include "lwip/memp.h"
00050 #include "lwip/snmp.h"
00051 #include "lwip/tcp.h"
00052 
00053 #include <string.h>
00054 
00055 /* Incremented every coarse grained timer shot (typically every 500 ms). */
00056 u32_t tcp_ticks;
00057 const u8_t tcp_backoff[13] =
00058     { 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7};
00059  /* Times per slowtmr hits */
00060 const u8_t tcp_persist_backoff[7] = { 3, 6, 12, 24, 48, 96, 120 };
00061 
00062 /* The TCP PCB lists. */
00063 
00064 /** List of all TCP PCBs bound but not yet (connected || listening) */
00065 struct tcp_pcb *tcp_bound_pcbs;  
00066 /** List of all TCP PCBs in LISTEN state */
00067 union tcp_listen_pcbs_t tcp_listen_pcbs;
00068 /** List of all TCP PCBs that are in a state in which
00069  * they accept or send data. */
00070 struct tcp_pcb *tcp_active_pcbs;  
00071 /** List of all TCP PCBs in TIME-WAIT state */
00072 struct tcp_pcb *tcp_tw_pcbs;
00073 
00074 struct tcp_pcb *tcp_tmp_pcb;
00075 
00076 static u8_t tcp_timer;
00077 static u16_t tcp_new_port(void);
00078 
00079 /**
00080  * Called periodically to dispatch TCP timers.
00081  *
00082  */
00083 void
00084 tcp_tmr(void)
00085 {
00086   /* Call tcp_fasttmr() every 250 ms */
00087   tcp_fasttmr();
00088 
00089   if (++tcp_timer & 1) {
00090     /* Call tcp_tmr() every 500 ms, i.e., every other timer
00091        tcp_tmr() is called. */
00092     tcp_slowtmr();
00093   }
00094 }
00095 
00096 /**
00097  * Closes the connection held by the PCB.
00098  *
00099  * Listening pcbs are freed and may not be referenced any more.
00100  * Connection pcbs are freed if not yet connected and may not be referenced
00101  * any more. If a connection is established (at least SYN received or in
00102  * a closing state), the connection is closed, and put in a closing state.
00103  * The pcb is then automatically freed in tcp_slowtmr(). It is therefore
00104  * unsafe to reference it.
00105  *
00106  * @param pcb the tcp_pcb to close
00107  * @return ERR_OK if connection has been closed
00108  *         another err_t if closing failed and pcb is not freed
00109  */
00110 err_t
00111 tcp_close(struct tcp_pcb *pcb)
00112 {
00113   err_t err;
00114 
00115 #if TCP_DEBUG
00116   LWIP_DEBUGF(TCP_DEBUG, ("tcp_close: closing in "));
00117   tcp_debug_print_state(pcb->state);
00118 #endif /* TCP_DEBUG */
00119 
00120   switch (pcb->state) {
00121   case CLOSED:
00122     /* Closing a pcb in the CLOSED state might seem erroneous,
00123      * however, it is in this state once allocated and as yet unused
00124      * and the user needs some way to free it should the need arise.
00125      * Calling tcp_close() with a pcb that has already been closed, (i.e. twice)
00126      * or for a pcb that has been used and then entered the CLOSED state 
00127      * is erroneous, but this should never happen as the pcb has in those cases
00128      * been freed, and so any remaining handles are bogus. */
00129     err = ERR_OK;
00130     TCP_RMV(&tcp_bound_pcbs, pcb);
00131     memp_free(MEMP_TCP_PCB, pcb);
00132     pcb = NULL;
00133     break;
00134   case LISTEN:
00135     err = ERR_OK;
00136     tcp_pcb_remove((struct tcp_pcb **)&tcp_listen_pcbs.pcbs, pcb);
00137     memp_free(MEMP_TCP_PCB_LISTEN, pcb);
00138     pcb = NULL;
00139     break;
00140   case SYN_SENT:
00141     err = ERR_OK;
00142     tcp_pcb_remove(&tcp_active_pcbs, pcb);
00143     memp_free(MEMP_TCP_PCB, pcb);
00144     pcb = NULL;
00145     snmp_inc_tcpattemptfails();
00146     break;
00147   case SYN_RCVD:
00148     err = tcp_send_ctrl(pcb, TCP_FIN);
00149     if (err == ERR_OK) {
00150       snmp_inc_tcpattemptfails();
00151       pcb->state = FIN_WAIT_1;
00152     }
00153     break;
00154   case ESTABLISHED:
00155     err = tcp_send_ctrl(pcb, TCP_FIN);
00156     if (err == ERR_OK) {
00157       snmp_inc_tcpestabresets();
00158       pcb->state = FIN_WAIT_1;
00159     }
00160     break;
00161   case CLOSE_WAIT:
00162     err = tcp_send_ctrl(pcb, TCP_FIN);
00163     if (err == ERR_OK) {
00164       snmp_inc_tcpestabresets();
00165       pcb->state = LAST_ACK;
00166     }
00167     break;
00168   default:
00169     /* Has already been closed, do nothing. */
00170     err = ERR_OK;
00171     pcb = NULL;
00172     break;
00173   }
00174 
00175   if (pcb != NULL && err == ERR_OK) {
00176     /* To ensure all data has been sent when tcp_close returns, we have
00177        to make sure tcp_output doesn't fail.
00178        Since we don't really have to ensure all data has been sent when tcp_close
00179        returns (unsent data is sent from tcp timer functions, also), we don't care
00180        for the return value of tcp_output for now. */
00181     /* @todo: When implementing SO_LINGER, this must be changed somehow:
00182        If SOF_LINGER is set, the data should be sent when tcp_close returns. */
00183     tcp_output(pcb);
00184   }
00185   return err;
00186 }
00187 
00188 /**
00189  * Aborts a connection by sending a RST to the remote host and deletes
00190  * the local protocol control block. This is done when a connection is
00191  * killed because of shortage of memory.
00192  *
00193  * @param pcb the tcp_pcb to abort
00194  */
00195 void
00196 tcp_abort(struct tcp_pcb *pcb)
00197 {
00198   u32_t seqno, ackno;
00199   u16_t remote_port, local_port;
00200   struct ip_addr remote_ip, local_ip;
00201 #if LWIP_CALLBACK_API  
00202   void (* errf)(void *arg, err_t err);
00203 #endif /* LWIP_CALLBACK_API */
00204   void *errf_arg;
00205 
00206   
00207   /* Figure out on which TCP PCB list we are, and remove us. If we
00208      are in an active state, call the receive function associated with
00209      the PCB with a NULL argument, and send an RST to the remote end. */
00210   if (pcb->state == TIME_WAIT) {
00211     tcp_pcb_remove(&tcp_tw_pcbs, pcb);
00212     memp_free(MEMP_TCP_PCB, pcb);
00213   } else {
00214     seqno = pcb->snd_nxt;
00215     ackno = pcb->rcv_nxt;
00216     ip_addr_set(&local_ip, &(pcb->local_ip));
00217     ip_addr_set(&remote_ip, &(pcb->remote_ip));
00218     local_port = pcb->local_port;
00219     remote_port = pcb->remote_port;
00220 #if LWIP_CALLBACK_API
00221     errf = pcb->errf;
00222 #endif /* LWIP_CALLBACK_API */
00223     errf_arg = pcb->callback_arg;
00224     tcp_pcb_remove(&tcp_active_pcbs, pcb);
00225     if (pcb->unacked != NULL) {
00226       tcp_segs_free(pcb->unacked);
00227     }
00228     if (pcb->unsent != NULL) {
00229       tcp_segs_free(pcb->unsent);
00230     }
00231 #if TCP_QUEUE_OOSEQ    
00232     if (pcb->ooseq != NULL) {
00233       tcp_segs_free(pcb->ooseq);
00234     }
00235 #endif /* TCP_QUEUE_OOSEQ */
00236     memp_free(MEMP_TCP_PCB, pcb);
00237     TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT);
00238     LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abort: sending RST\n"));
00239     tcp_rst(seqno, ackno, &local_ip, &remote_ip, local_port, remote_port);
00240   }
00241 }
00242 
00243 /**
00244  * Binds the connection to a local portnumber and IP address. If the
00245  * IP address is not given (i.e., ipaddr == NULL), the IP address of
00246  * the outgoing network interface is used instead.
00247  *
00248  * @param pcb the tcp_pcb to bind (no check is done whether this pcb is
00249  *        already bound!)
00250  * @param ipaddr the local ip address to bind to (use IP_ADDR_ANY to bind
00251  *        to any local address
00252  * @param port the local port to bind to
00253  * @return ERR_USE if the port is already in use
00254  *         ERR_OK if bound
00255  */
00256 err_t
00257 tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
00258 {
00259   struct tcp_pcb *cpcb;
00260 
00261   LWIP_ERROR("tcp_connect: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_ISCONN);
00262 
00263   if (port == 0) {
00264     port = tcp_new_port();
00265   }
00266   /* Check if the address already is in use. */
00267   /* Check the listen pcbs. */
00268   for(cpcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs;
00269       cpcb != NULL; cpcb = cpcb->next) {
00270     if (cpcb->local_port == port) {
00271       if (ip_addr_isany(&(cpcb->local_ip)) ||
00272           ip_addr_isany(ipaddr) ||
00273           ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {
00274         return ERR_USE;
00275       }
00276     }
00277   }
00278   /* Check the connected pcbs. */
00279   for(cpcb = tcp_active_pcbs;
00280       cpcb != NULL; cpcb = cpcb->next) {
00281     if (cpcb->local_port == port) {
00282       if (ip_addr_isany(&(cpcb->local_ip)) ||
00283           ip_addr_isany(ipaddr) ||
00284           ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {
00285         return ERR_USE;
00286       }
00287     }
00288   }
00289   /* Check the bound, not yet connected pcbs. */
00290   for(cpcb = tcp_bound_pcbs; cpcb != NULL; cpcb = cpcb->next) {
00291     if (cpcb->local_port == port) {
00292       if (ip_addr_isany(&(cpcb->local_ip)) ||
00293           ip_addr_isany(ipaddr) ||
00294           ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {
00295         return ERR_USE;
00296       }
00297     }
00298   }
00299   /* @todo: until SO_REUSEADDR is implemented (see task #6995 on savannah),
00300    * we have to check the pcbs in TIME-WAIT state, also: */
00301   for(cpcb = tcp_tw_pcbs; cpcb != NULL; cpcb = cpcb->next) {
00302     if (cpcb->local_port == port) {
00303       if (ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {
00304         return ERR_USE;
00305       }
00306     }
00307   }
00308 
00309   if (!ip_addr_isany(ipaddr)) {
00310     pcb->local_ip = *ipaddr;
00311   }
00312   pcb->local_port = port;
00313   TCP_REG(&tcp_bound_pcbs, pcb);
00314   LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %"U16_F"\n", port));
00315   return ERR_OK;
00316 }
00317 #if LWIP_CALLBACK_API
00318 /**
00319  * Default accept callback if no accept callback is specified by the user.
00320  */
00321 static err_t
00322 tcp_accept_null(void *arg, struct tcp_pcb *pcb, err_t err)
00323 {
00324   LWIP_UNUSED_ARG(arg);
00325   LWIP_UNUSED_ARG(pcb);
00326   LWIP_UNUSED_ARG(err);
00327 
00328   return ERR_ABRT;
00329 }
00330 #endif /* LWIP_CALLBACK_API */
00331 
00332 /**
00333  * Set the state of the connection to be LISTEN, which means that it
00334  * is able to accept incoming connections. The protocol control block
00335  * is reallocated in order to consume less memory. Setting the
00336  * connection to LISTEN is an irreversible process.
00337  *
00338  * @param pcb the original tcp_pcb
00339  * @param backlog the incoming connections queue limit
00340  * @return tcp_pcb used for listening, consumes less memory.
00341  *
00342  * @note The original tcp_pcb is freed. This function therefore has to be
00343  *       called like this:
00344  *             tpcb = tcp_listen(tpcb);
00345  */
00346 struct tcp_pcb *
00347 tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
00348 {
00349   struct tcp_pcb_listen *lpcb;
00350 
00351   LWIP_UNUSED_ARG(backlog);
00352   LWIP_ERROR("tcp_listen: pcb already connected", pcb->state == CLOSED, return NULL);
00353 
00354   /* already listening? */
00355   if (pcb->state == LISTEN) {
00356     return pcb;
00357   }
00358   lpcb = static_cast<struct tcp_pcb_listen *>(memp_malloc(MEMP_TCP_PCB_LISTEN));
00359   if (lpcb == NULL) {
00360     return NULL;
00361   }
00362   lpcb->callback_arg = pcb->callback_arg;
00363   lpcb->local_port = pcb->local_port;
00364   lpcb->state = LISTEN;
00365   lpcb->so_options = pcb->so_options;
00366   lpcb->so_options |= SOF_ACCEPTCONN;
00367   lpcb->ttl = pcb->ttl;
00368   lpcb->tos = pcb->tos;
00369   ip_addr_set(&lpcb->local_ip, &pcb->local_ip);
00370   TCP_RMV(&tcp_bound_pcbs, pcb);
00371   memp_free(MEMP_TCP_PCB, pcb);
00372 #if LWIP_CALLBACK_API
00373   lpcb->accept = tcp_accept_null;
00374 #endif /* LWIP_CALLBACK_API */
00375 #if TCP_LISTEN_BACKLOG
00376   lpcb->accepts_pending = 0;
00377   lpcb->backlog = (backlog ? backlog : 1);
00378 #endif /* TCP_LISTEN_BACKLOG */
00379   TCP_REG(&tcp_listen_pcbs.listen_pcbs, lpcb);
00380   return (struct tcp_pcb *)lpcb;
00381 }
00382 
00383 /**
00384  * This function should be called by the application when it has
00385  * processed the data. The purpose is to advertise a larger window
00386  * when the data has been processed.
00387  *
00388  * @param pcb the tcp_pcb for which data is read
00389  * @param len the amount of bytes that have been read by the application
00390  */
00391 void
00392 tcp_recved(struct tcp_pcb *pcb, u16_t len)
00393 {
00394   if ((u32_t)pcb->rcv_wnd + len > TCP_WND) {
00395     pcb->rcv_wnd = TCP_WND;
00396     pcb->rcv_ann_wnd = TCP_WND;
00397   } else {
00398     pcb->rcv_wnd += len;
00399     if (pcb->rcv_wnd >= pcb->mss) {
00400       pcb->rcv_ann_wnd = pcb->rcv_wnd;
00401     }
00402   }
00403 
00404   if (!(pcb->flags & TF_ACK_DELAY) &&
00405      !(pcb->flags & TF_ACK_NOW)) {
00406     /*
00407      * We send an ACK here (if one is not already pending, hence
00408      * the above tests) as tcp_recved() implies that the application
00409      * has processed some data, and so we can open the receiver's
00410      * window to allow more to be transmitted.  This could result in
00411      * two ACKs being sent for each received packet in some limited cases
00412      * (where the application is only receiving data, and is slow to
00413      * process it) but it is necessary to guarantee that the sender can
00414      * continue to transmit.
00415      */
00416     tcp_ack(pcb);
00417   } 
00418   else if (pcb->flags & TF_ACK_DELAY && pcb->rcv_wnd >= TCP_WND/2) {
00419     /* If we can send a window update such that there is a full
00420      * segment available in the window, do so now.  This is sort of
00421      * nagle-like in its goals, and tries to hit a compromise between
00422      * sending acks each time the window is updated, and only sending
00423      * window updates when a timer expires.  The "threshold" used
00424      * above (currently TCP_WND/2) can be tuned to be more or less
00425      * aggressive  */
00426     tcp_ack_now(pcb);
00427   }
00428 
00429   LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: recveived %"U16_F" bytes, wnd %"U16_F" (%"U16_F").\n",
00430          len, pcb->rcv_wnd, TCP_WND - pcb->rcv_wnd));
00431 }
00432 
00433 /**
00434  * A nastly hack featuring 'goto' statements that allocates a
00435  * new TCP local port.
00436  *
00437  * @return a new (free) local TCP port number
00438  */
00439 static u16_t
00440 tcp_new_port(void)
00441 {
00442   struct tcp_pcb *pcb;
00443 #ifndef TCP_LOCAL_PORT_RANGE_START
00444 #define TCP_LOCAL_PORT_RANGE_START 4096
00445 #define TCP_LOCAL_PORT_RANGE_END   0x7fff
00446 #endif
00447   static u16_t port = TCP_LOCAL_PORT_RANGE_START;
00448   
00449  again:
00450   if (++port > TCP_LOCAL_PORT_RANGE_END) {
00451     port = TCP_LOCAL_PORT_RANGE_START;
00452   }
00453   
00454   for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
00455     if (pcb->local_port == port) {
00456       goto again;
00457     }
00458   }
00459   for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
00460     if (pcb->local_port == port) {
00461       goto again;
00462     }
00463   }
00464   for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) {
00465     if (pcb->local_port == port) {
00466       goto again;
00467     }
00468   }
00469   return port;
00470 }
00471 
00472 /**
00473  * Connects to another host. The function given as the "connected"
00474  * argument will be called when the connection has been established.
00475  *
00476  * @param pcb the tcp_pcb used to establish the connection
00477  * @param ipaddr the remote ip address to connect to
00478  * @param port the remote tcp port to connect to
00479  * @param connected callback function to call when connected (or on error)
00480  * @return ERR_VAL if invalid arguments are given
00481  *         ERR_OK if connect request has been sent
00482  *         other err_t values if connect request couldn't be sent
00483  */
00484 err_t
00485 tcp_connect(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port,
00486       err_t (* connected)(void *arg, struct tcp_pcb *tpcb, err_t err))
00487 {
00488   u32_t optdata;
00489   err_t ret;
00490   u32_t iss;
00491 
00492   LWIP_ERROR("tcp_connect: can only connected from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN);
00493 
00494   LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port));
00495   if (ipaddr != NULL) {
00496     pcb->remote_ip = *ipaddr;
00497   } else {
00498     return ERR_VAL;
00499   }
00500   pcb->remote_port = port;
00501   if (pcb->local_port == 0) {
00502     pcb->local_port = tcp_new_port();
00503   }
00504   iss = tcp_next_iss();
00505   pcb->rcv_nxt = 0;
00506   pcb->snd_nxt = iss;
00507   pcb->lastack = iss - 1;
00508   pcb->snd_lbb = iss - 1;
00509   pcb->rcv_wnd = TCP_WND;
00510   pcb->rcv_ann_wnd = TCP_WND;
00511   pcb->snd_wnd = TCP_WND;
00512   /* The send MSS is updated when an MSS option is received. */
00513   pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS;
00514 #if TCP_CALCULATE_EFF_SEND_MSS
00515   pcb->mss = tcp_eff_send_mss(pcb->mss, ipaddr);
00516 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
00517   pcb->cwnd = 1;
00518   pcb->ssthresh = pcb->mss * 10;
00519   pcb->state = SYN_SENT;
00520 #if LWIP_CALLBACK_API  
00521   pcb->connected = connected;
00522 #endif /* LWIP_CALLBACK_API */
00523   TCP_RMV(&tcp_bound_pcbs, pcb);
00524   TCP_REG(&tcp_active_pcbs, pcb);
00525 
00526   snmp_inc_tcpactiveopens();
00527   
00528   /* Build an MSS option */
00529   optdata = TCP_BUILD_MSS_OPTION();
00530 
00531   ret = tcp_enqueue(pcb, NULL, 0, TCP_SYN, 0, (u8_t *)&optdata, 4);
00532   if (ret == ERR_OK) { 
00533     tcp_output(pcb);
00534   }
00535   return ret;
00536 } 
00537 
00538 /**
00539  * Called every 500 ms and implements the retransmission timer and the timer that
00540  * removes PCBs that have been in TIME-WAIT for enough time. It also increments
00541  * various timers such as the inactivity timer in each PCB.
00542  *
00543  * Automatically called from tcp_tmr().
00544  */
00545 void
00546 tcp_slowtmr(void)
00547 {
00548   struct tcp_pcb *pcb, *pcb2, *prev;
00549   u16_t eff_wnd;
00550   u8_t pcb_remove;      /* flag if a PCB should be removed */
00551   err_t err;
00552 
00553   err = ERR_OK;
00554 
00555   ++tcp_ticks;
00556 
00557   /* Steps through all of the active PCBs. */
00558   prev = NULL;
00559   pcb = tcp_active_pcbs;
00560   if (pcb == NULL) {
00561     LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n"));
00562   }
00563   while (pcb != NULL) {
00564     LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb\n"));
00565     LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED);
00566     LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN);
00567     LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT);
00568 
00569     pcb_remove = 0;
00570 
00571     if (pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) {
00572       ++pcb_remove;
00573       LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n"));
00574     }
00575     else if (pcb->nrtx == TCP_MAXRTX) {
00576       ++pcb_remove;
00577       LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n"));
00578     } else {
00579       if (pcb->persist_backoff > 0) {
00580         /* If snd_wnd is zero, use persist timer to send 1 byte probes
00581          * instead of using the standard retransmission mechanism. */
00582         pcb->persist_cnt++;
00583         if (pcb->persist_cnt >= tcp_persist_backoff[pcb->persist_backoff-1]) {
00584           pcb->persist_cnt = 0;
00585           if (pcb->persist_backoff < sizeof(tcp_persist_backoff)) {
00586             pcb->persist_backoff++;
00587           }
00588           tcp_zero_window_probe(pcb);
00589         }
00590       } else {
00591         /* Increase the retransmission timer if it is running */
00592         if(pcb->rtime >= 0)
00593           ++pcb->rtime;
00594 
00595         if (pcb->unacked != NULL && pcb->rtime >= pcb->rto) {
00596           /* Time for a retransmission. */
00597           LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %"S16_F
00598                                       " pcb->rto %"S16_F"\n",
00599                                       pcb->rtime, pcb->rto));
00600 
00601           /* Double retransmission time-out unless we are trying to
00602            * connect to somebody (i.e., we are in SYN_SENT). */
00603           if (pcb->state != SYN_SENT) {
00604             pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx];
00605           }
00606 
00607           /* Reset the retransmission timer. */
00608           pcb->rtime = 0;
00609 
00610           /* Reduce congestion window and ssthresh. */
00611           eff_wnd = LWIP_MIN(pcb->cwnd, pcb->snd_wnd);
00612           pcb->ssthresh = eff_wnd >> 1;
00613           if (pcb->ssthresh < pcb->mss) {
00614             pcb->ssthresh = pcb->mss * 2;
00615           }
00616           pcb->cwnd = pcb->mss;
00617           LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: cwnd %"U16_F
00618                                        " ssthresh %"U16_F"\n",
00619                                        pcb->cwnd, pcb->ssthresh));
00620  
00621           /* The following needs to be called AFTER cwnd is set to one
00622              mss - STJ */
00623           tcp_rexmit_rto(pcb);
00624         }
00625       }
00626     }
00627     /* Check if this PCB has stayed too long in FIN-WAIT-2 */
00628     if (pcb->state == FIN_WAIT_2) {
00629       if ((u32_t)(tcp_ticks - pcb->tmr) >
00630           TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) {
00631         ++pcb_remove;
00632         LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n"));
00633       }
00634     }
00635 
00636     /* Check if KEEPALIVE should be sent */
00637     if((pcb->so_options & SOF_KEEPALIVE) && 
00638        ((pcb->state == ESTABLISHED) || 
00639         (pcb->state == CLOSE_WAIT))) {
00640 #if LWIP_TCP_KEEPALIVE
00641       if((u32_t)(tcp_ticks - pcb->tmr) > 
00642          (pcb->keep_idle + (pcb->keep_cnt*pcb->keep_intvl))
00643          / TCP_SLOW_INTERVAL)
00644 #else      
00645       if((u32_t)(tcp_ticks - pcb->tmr) > 
00646          (pcb->keep_idle + TCP_MAXIDLE) / TCP_SLOW_INTERVAL)
00647 #endif /* LWIP_TCP_KEEPALIVE */
00648       {
00649         LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to %"U16_F".%"U16_F".%"U16_F".%"U16_F".\n",
00650                                 ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
00651                                 ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip)));
00652         
00653         tcp_abort(pcb);
00654       }
00655 #if LWIP_TCP_KEEPALIVE
00656       else if((u32_t)(tcp_ticks - pcb->tmr) > 
00657               (pcb->keep_idle + pcb->keep_cnt_sent * pcb->keep_intvl)
00658               / TCP_SLOW_INTERVAL)
00659 #else
00660       else if((u32_t)(tcp_ticks - pcb->tmr) > 
00661               (pcb->keep_idle + pcb->keep_cnt_sent * TCP_KEEPINTVL_DEFAULT) 
00662               / TCP_SLOW_INTERVAL)
00663 #endif /* LWIP_TCP_KEEPALIVE */
00664       {
00665         tcp_keepalive(pcb);
00666         pcb->keep_cnt_sent++;
00667       }
00668     }
00669 
00670     /* If this PCB has queued out of sequence data, but has been
00671        inactive for too long, will drop the data (it will eventually
00672        be retransmitted). */
00673 #if TCP_QUEUE_OOSEQ    
00674     if (pcb->ooseq != NULL &&
00675         (u32_t)tcp_ticks - pcb->tmr >= pcb->rto * TCP_OOSEQ_TIMEOUT) {
00676       tcp_segs_free(pcb->ooseq);
00677       pcb->ooseq = NULL;
00678       LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: dropping OOSEQ queued data\n"));
00679     }
00680 #endif /* TCP_QUEUE_OOSEQ */
00681 
00682     /* Check if this PCB has stayed too long in SYN-RCVD */
00683     if (pcb->state == SYN_RCVD) {
00684       if ((u32_t)(tcp_ticks - pcb->tmr) >
00685           TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) {
00686         ++pcb_remove;
00687         LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n"));
00688       }
00689     }
00690 
00691     /* Check if this PCB has stayed too long in LAST-ACK */
00692     if (pcb->state == LAST_ACK) {
00693       if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {
00694         ++pcb_remove;
00695         LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in LAST-ACK\n"));
00696       }
00697     }
00698 
00699     /* If the PCB should be removed, do it. */
00700     if (pcb_remove) {
00701       tcp_pcb_purge(pcb);      
00702       /* Remove PCB from tcp_active_pcbs list. */
00703       if (prev != NULL) {
00704         LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs);
00705         prev->next = pcb->next;
00706       } else {
00707         /* This PCB was the first. */
00708         LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb);
00709         tcp_active_pcbs = pcb->next;
00710       }
00711 
00712       TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_ABRT);
00713 
00714       pcb2 = pcb->next;
00715       memp_free(MEMP_TCP_PCB, pcb);
00716       pcb = pcb2;
00717     } else {
00718 
00719       /* We check if we should poll the connection. */
00720       ++pcb->polltmr;
00721       if (pcb->polltmr >= pcb->pollinterval) {
00722         pcb->polltmr = 0;
00723         LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n"));
00724         TCP_EVENT_POLL(pcb, err);
00725         if (err == ERR_OK) {
00726           tcp_output(pcb);
00727         }
00728       }
00729       
00730       prev = pcb;
00731       pcb = pcb->next;
00732     }
00733   }
00734 
00735   
00736   /* Steps through all of the TIME-WAIT PCBs. */
00737   prev = NULL;    
00738   pcb = tcp_tw_pcbs;
00739   while (pcb != NULL) {
00740     LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
00741     pcb_remove = 0;
00742 
00743     /* Check if this PCB has stayed long enough in TIME-WAIT */
00744     if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {
00745       ++pcb_remove;
00746     }
00747     
00748 
00749 
00750     /* If the PCB should be removed, do it. */
00751     if (pcb_remove) {
00752       tcp_pcb_purge(pcb);      
00753       /* Remove PCB from tcp_tw_pcbs list. */
00754       if (prev != NULL) {
00755         LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs);
00756         prev->next = pcb->next;
00757       } else {
00758         /* This PCB was the first. */
00759         LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb);
00760         tcp_tw_pcbs = pcb->next;
00761       }
00762       pcb2 = pcb->next;
00763       memp_free(MEMP_TCP_PCB, pcb);
00764       pcb = pcb2;
00765     } else {
00766       prev = pcb;
00767       pcb = pcb->next;
00768     }
00769   }
00770 }
00771 
00772 /**
00773  * Is called every TCP_FAST_INTERVAL (250 ms) and process data previously
00774  * "refused" by upper layer (application) and sends delayed ACKs.
00775  *
00776  * Automatically called from tcp_tmr().
00777  */
00778 void
00779 tcp_fasttmr(void)
00780 {
00781   struct tcp_pcb *pcb;
00782 
00783   for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
00784     /* If there is data which was previously "refused" by upper layer */
00785     if (pcb->refused_data != NULL) {
00786       /* Notify again application with data previously received. */
00787       err_t err;
00788       LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_fasttmr: notify kept packet\n"));
00789       TCP_EVENT_RECV(pcb, pcb->refused_data, ERR_OK, err);
00790       if (err == ERR_OK) {
00791         pcb->refused_data = NULL;
00792       }
00793     }
00794 
00795     /* send delayed ACKs */  
00796     if (pcb->flags & TF_ACK_DELAY) {
00797       LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n"));
00798       tcp_ack_now(pcb);
00799       pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
00800     }
00801   }
00802 }
00803 
00804 /**
00805  * Deallocates a list of TCP segments (tcp_seg structures).
00806  *
00807  * @param seg tcp_seg list of TCP segments to free
00808  * @return the number of pbufs that were deallocated
00809  */
00810 u8_t
00811 tcp_segs_free(struct tcp_seg *seg)
00812 {
00813   u8_t count = 0;
00814   struct tcp_seg *next;
00815   while (seg != NULL) {
00816     next = seg->next;
00817     count += tcp_seg_free(seg);
00818     seg = next;
00819   }
00820   return count;
00821 }
00822 
00823 /**
00824  * Frees a TCP segment (tcp_seg structure).
00825  *
00826  * @param seg single tcp_seg to free
00827  * @return the number of pbufs that were deallocated
00828  */
00829 u8_t
00830 tcp_seg_free(struct tcp_seg *seg)
00831 {
00832   u8_t count = 0;
00833   
00834   if (seg != NULL) {
00835     if (seg->p != NULL) {
00836       count = pbuf_free(seg->p);
00837 #if TCP_DEBUG
00838       seg->p = NULL;
00839 #endif /* TCP_DEBUG */
00840     }
00841     memp_free(MEMP_TCP_SEG, seg);
00842   }
00843   return count;
00844 }
00845 
00846 /**
00847  * Sets the priority of a connection.
00848  *
00849  * @param pcb the tcp_pcb to manipulate
00850  * @param prio new priority
00851  */
00852 void
00853 tcp_setprio(struct tcp_pcb *pcb, u8_t prio)
00854 {
00855   pcb->prio = prio;
00856 }
00857 #if TCP_QUEUE_OOSEQ
00858 
00859 /**
00860  * Returns a copy of the given TCP segment.
00861  * The pbuf and data are not copied, only the pointers
00862  *
00863  * @param seg the old tcp_seg
00864  * @return a copy of seg
00865  */ 
00866 struct tcp_seg *
00867 tcp_seg_copy(struct tcp_seg *seg)
00868 {
00869   struct tcp_seg *cseg;
00870 
00871   cseg = static_cast<struct tcp_seg *>(memp_malloc(MEMP_TCP_SEG));
00872   if (cseg == NULL) {
00873     return NULL;
00874   }
00875   SMEMCPY((u8_t *)cseg, (const u8_t *)seg, sizeof(struct tcp_seg)); 
00876   pbuf_ref(cseg->p);
00877   return cseg;
00878 }
00879 #endif
00880 
00881 #if LWIP_CALLBACK_API
00882 /**
00883  * Default receive callback that is called if the user didn't register
00884  * a recv callback for the pcb.
00885  */
00886 static err_t
00887 tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
00888 {
00889   arg = arg;
00890   if (p != NULL) {
00891     pbuf_free(p);
00892   } else if (err == ERR_OK) {
00893     return tcp_close(pcb);
00894   }
00895   return ERR_OK;
00896 }
00897 #endif /* LWIP_CALLBACK_API */
00898 
00899 /**
00900  * Kills the oldest active connection that has lower priority than prio.
00901  *
00902  * @param prio minimum priority
00903  */
00904 static void
00905 tcp_kill_prio(u8_t prio)
00906 {
00907   struct tcp_pcb *pcb, *inactive;
00908   u32_t inactivity;
00909   u8_t mprio;
00910 
00911 
00912   mprio = TCP_PRIO_MAX;
00913   
00914   /* We kill the oldest active connection that has lower priority than prio. */
00915   inactivity = 0;
00916   inactive = NULL;
00917   for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
00918     if (pcb->prio <= prio &&
00919        pcb->prio <= mprio &&
00920        (u32_t)(tcp_ticks - pcb->tmr) >= inactivity) {
00921       inactivity = tcp_ticks - pcb->tmr;
00922       inactive = pcb;
00923       mprio = pcb->prio;
00924     }
00925   }
00926   if (inactive != NULL) {
00927     LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB %p (%"S32_F")\n",
00928            (void *)inactive, inactivity));
00929     tcp_abort(inactive);
00930   }      
00931 }
00932 
00933 /**
00934  * Kills the oldest connection that is in TIME_WAIT state.
00935  * Called from tcp_alloc() if no more connections are available.
00936  */
00937 static void
00938 tcp_kill_timewait(void)
00939 {
00940   struct tcp_pcb *pcb, *inactive;
00941   u32_t inactivity;
00942 
00943   inactivity = 0;
00944   inactive = NULL;
00945   /* Go through the list of TIME_WAIT pcbs and get the oldest pcb. */
00946   for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
00947     if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) {
00948       inactivity = tcp_ticks - pcb->tmr;
00949       inactive = pcb;
00950     }
00951   }
00952   if (inactive != NULL) {
00953     LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB %p (%"S32_F")\n",
00954            (void *)inactive, inactivity));
00955     tcp_abort(inactive);
00956   }      
00957 }
00958 
00959 /**
00960  * Allocate a new tcp_pcb structure.
00961  *
00962  * @param prio priority for the new pcb
00963  * @return a new tcp_pcb that initially is in state CLOSED
00964  */
00965 struct tcp_pcb *
00966 tcp_alloc(u8_t prio)
00967 {
00968   struct tcp_pcb *pcb;
00969   u32_t iss;
00970   
00971   pcb = static_cast<struct tcp_pcb *>(memp_malloc(MEMP_TCP_PCB));
00972   if (pcb == NULL) {
00973     /* Try killing oldest connection in TIME-WAIT. */
00974     LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest TIME-WAIT connection\n"));
00975     tcp_kill_timewait();
00976     /* Try to allocate a tcp_pcb again. */
00977     pcb = static_cast<struct tcp_pcb *>(memp_malloc(MEMP_TCP_PCB));
00978     if (pcb == NULL) {
00979       /* Try killing active connections with lower priority than the new one. */
00980       tcp_kill_prio(prio);
00981       /* Try to allocate a tcp_pcb again. */
00982       pcb = static_cast<struct tcp_pcb *>(memp_malloc(MEMP_TCP_PCB));
00983     }
00984   }
00985   if (pcb != NULL) {
00986     memset(pcb, 0, sizeof(struct tcp_pcb));
00987     pcb->prio = TCP_PRIO_NORMAL;
00988     pcb->snd_buf = TCP_SND_BUF;
00989     pcb->snd_queuelen = 0;
00990     pcb->rcv_wnd = TCP_WND;
00991     pcb->rcv_ann_wnd = TCP_WND;
00992     pcb->tos = 0;
00993     pcb->ttl = TCP_TTL;
00994     /* The send MSS is updated when an MSS option is received. */
00995     pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS;
00996     pcb->rto = 3000 / TCP_SLOW_INTERVAL;
00997     pcb->sa = 0;
00998     pcb->sv = 3000 / TCP_SLOW_INTERVAL;
00999     pcb->rtime = -1;
01000     pcb->cwnd = 1;
01001     iss = tcp_next_iss();
01002     pcb->snd_wl2 = iss;
01003     pcb->snd_nxt = iss;
01004     pcb->snd_max = iss;
01005     pcb->lastack = iss;
01006     pcb->snd_lbb = iss;   
01007     pcb->tmr = tcp_ticks;
01008 
01009     pcb->polltmr = 0;
01010 
01011 #if LWIP_CALLBACK_API
01012     pcb->recv = tcp_recv_null;
01013 #endif /* LWIP_CALLBACK_API */  
01014     
01015     /* Init KEEPALIVE timer */
01016     pcb->keep_idle  = TCP_KEEPIDLE_DEFAULT;
01017     
01018 #if LWIP_TCP_KEEPALIVE
01019     pcb->keep_intvl = TCP_KEEPINTVL_DEFAULT;
01020     pcb->keep_cnt   = TCP_KEEPCNT_DEFAULT;
01021 #endif /* LWIP_TCP_KEEPALIVE */
01022 
01023     pcb->keep_cnt_sent = 0;
01024   }
01025   return pcb;
01026 }
01027 
01028 /**
01029  * Creates a new TCP protocol control block but doesn't place it on
01030  * any of the TCP PCB lists.
01031  * The pcb is not put on any list until binding using tcp_bind().
01032  *
01033  * @internal: Maybe there should be a idle TCP PCB list where these
01034  * PCBs are put on. Port reservation using tcp_bind() is implemented but
01035  * allocated pcbs that are not bound can't be killed automatically if wanting
01036  * to allocate a pcb with higher prio (@see tcp_kill_prio())
01037  *
01038  * @return a new tcp_pcb that initially is in state CLOSED
01039  */
01040 struct tcp_pcb *
01041 tcp_new(void)
01042 {
01043   return tcp_alloc(TCP_PRIO_NORMAL);
01044 }
01045 
01046 /**
01047  * Used to specify the argument that should be passed callback
01048  * functions.
01049  *
01050  * @param pcb tcp_pcb to set the callback argument
01051  * @param arg void pointer argument to pass to callback functions
01052  */ 
01053 void
01054 tcp_arg(struct tcp_pcb *pcb, void *arg)
01055 {  
01056   pcb->callback_arg = arg;
01057 }
01058 #if LWIP_CALLBACK_API
01059 
01060 /**
01061  * Used to specify the function that should be called when a TCP
01062  * connection receives data.
01063  *
01064  * @param pcb tcp_pcb to set the recv callback
01065  * @param recv callback function to call for this pcb when data is received
01066  */ 
01067 void
01068 tcp_recv(struct tcp_pcb *pcb,
01069    err_t (* recv)(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err))
01070 {
01071   pcb->recv = recv;
01072 }
01073 
01074 /**
01075  * Used to specify the function that should be called when TCP data
01076  * has been successfully delivered to the remote host.
01077  *
01078  * @param pcb tcp_pcb to set the sent callback
01079  * @param sent callback function to call for this pcb when data is successfully sent
01080  */ 
01081 void
01082 tcp_sent(struct tcp_pcb *pcb,
01083    err_t (* sent)(void *arg, struct tcp_pcb *tpcb, u16_t len))
01084 {
01085   pcb->sent = sent;
01086 }
01087 
01088 /**
01089  * Used to specify the function that should be called when a fatal error
01090  * has occured on the connection.
01091  *
01092  * @param pcb tcp_pcb to set the err callback
01093  * @param errf callback function to call for this pcb when a fatal error
01094  *        has occured on the connection
01095  */ 
01096 void
01097 tcp_err(struct tcp_pcb *pcb,
01098    void (* errf)(void *arg, err_t err))
01099 {
01100   pcb->errf = errf;
01101 }
01102 
01103 /**
01104  * Used for specifying the function that should be called when a
01105  * LISTENing connection has been connected to another host.
01106  *
01107  * @param pcb tcp_pcb to set the accept callback
01108  * @param accept callback function to call for this pcb when LISTENing
01109  *        connection has been connected to another host
01110  */ 
01111 void
01112 tcp_accept(struct tcp_pcb *pcb,
01113      err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err))
01114 {
01115   ((struct tcp_pcb_listen *)pcb)->accept = accept;
01116 }
01117 #endif /* LWIP_CALLBACK_API */
01118 
01119 
01120 /**
01121  * Used to specify the function that should be called periodically
01122  * from TCP. The interval is specified in terms of the TCP coarse
01123  * timer interval, which is called twice a second.
01124  *
01125  */ 
01126 void
01127 tcp_poll(struct tcp_pcb *pcb,
01128    err_t (* poll)(void *arg, struct tcp_pcb *tpcb), u8_t interval)
01129 {
01130 #if LWIP_CALLBACK_API
01131   pcb->poll = poll;
01132 #endif /* LWIP_CALLBACK_API */  
01133   pcb->pollinterval = interval;
01134 }
01135 
01136 /**
01137  * Purges a TCP PCB. Removes any buffered data and frees the buffer memory
01138  * (pcb->ooseq, pcb->unsent and pcb->unacked are freed).
01139  *
01140  * @param pcb tcp_pcb to purge. The pcb itself is not deallocated!
01141  */
01142 void
01143 tcp_pcb_purge(struct tcp_pcb *pcb)
01144 {
01145   if (pcb->state != CLOSED &&
01146      pcb->state != TIME_WAIT &&
01147      pcb->state != LISTEN) {
01148 
01149     LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge\n"));
01150 
01151     if (pcb->refused_data != NULL) {
01152       LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->refused_data\n"));
01153       pbuf_free(pcb->refused_data);
01154       pcb->refused_data = NULL;
01155     }
01156     if (pcb->unsent != NULL) {
01157       LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: not all data sent\n"));
01158     }
01159     if (pcb->unacked != NULL) {
01160       LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->unacked\n"));
01161     }
01162 #if TCP_QUEUE_OOSEQ /* LW */
01163     if (pcb->ooseq != NULL) {
01164       LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n"));
01165     }
01166 
01167     /* Stop the retransmission timer as it will expect data on unacked
01168        queue if it fires */
01169     pcb->rtime = -1;
01170 
01171     tcp_segs_free(pcb->ooseq);
01172     pcb->ooseq = NULL;
01173 #endif /* TCP_QUEUE_OOSEQ */
01174     tcp_segs_free(pcb->unsent);
01175     tcp_segs_free(pcb->unacked);
01176     pcb->unacked = pcb->unsent = NULL;
01177   }
01178 }
01179 
01180 /**
01181  * Purges the PCB and removes it from a PCB list. Any delayed ACKs are sent first.
01182  *
01183  * @param pcblist PCB list to purge.
01184  * @param pcb tcp_pcb to purge. The pcb itself is also deallocated!
01185  */
01186 void
01187 tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb)
01188 {
01189   TCP_RMV(pcblist, pcb);
01190 
01191   tcp_pcb_purge(pcb);
01192   
01193   /* if there is an outstanding delayed ACKs, send it */
01194   if (pcb->state != TIME_WAIT &&
01195      pcb->state != LISTEN &&
01196      pcb->flags & TF_ACK_DELAY) {
01197     pcb->flags |= TF_ACK_NOW;
01198     tcp_output(pcb);
01199   }
01200 
01201   if (pcb->state != LISTEN) {
01202     LWIP_ASSERT("unsent segments leaking", pcb->unsent == NULL);
01203     LWIP_ASSERT("unacked segments leaking", pcb->unacked == NULL);
01204 #if TCP_QUEUE_OOSEQ
01205     LWIP_ASSERT("ooseq segments leaking", pcb->ooseq == NULL);
01206 #endif /* TCP_QUEUE_OOSEQ */
01207   }
01208 
01209   pcb->state = CLOSED;
01210 
01211   LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane());
01212 }
01213 
01214 /**
01215  * Calculates a new initial sequence number for new connections.
01216  *
01217  * @return u32_t pseudo random sequence number
01218  */
01219 u32_t
01220 tcp_next_iss(void)
01221 {
01222   static u32_t iss = 6510;
01223   
01224   iss += tcp_ticks;       /* XXX */
01225   return iss;
01226 }
01227 
01228 #if TCP_CALCULATE_EFF_SEND_MSS
01229 /**
01230  * Calcluates the effective send mss that can be used for a specific IP address
01231  * by using ip_route to determin the netif used to send to the address and
01232  * calculating the minimum of TCP_MSS and that netif's mtu (if set).
01233  */
01234 u16_t
01235 tcp_eff_send_mss(u16_t sendmss, struct ip_addr *addr)
01236 {
01237   u16_t mss_s;
01238   struct netif *outif;
01239 
01240   outif = ip_route(addr);
01241   if ((outif != NULL) && (outif->mtu != 0)) {
01242     mss_s = outif->mtu - IP_HLEN - TCP_HLEN;
01243     /* RFC 1122, chap 4.2.2.6:
01244      * Eff.snd.MSS = min(SendMSS+20, MMS_S) - TCPhdrsize - IPoptionsize
01245      * but we only send options with SYN and that is never filled with data! */
01246     sendmss = LWIP_MIN(sendmss, mss_s);
01247   }
01248   return sendmss;
01249 }
01250 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
01251 
01252 #if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG
01253 /**
01254  * Print a tcp header for debugging purposes.
01255  *
01256  * @param tcphdr pointer to a struct tcp_hdr
01257  */
01258 void
01259 tcp_debug_print(struct tcp_hdr *tcphdr)
01260 {
01261   LWIP_DEBUGF(TCP_DEBUG, ("TCP header:\n"));
01262   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
01263   LWIP_DEBUGF(TCP_DEBUG, ("|    %5"U16_F"      |    %5"U16_F"      | (src port, dest port)\n",
01264          ntohs(tcphdr->src), ntohs(tcphdr->dest)));
01265   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
01266   LWIP_DEBUGF(TCP_DEBUG, ("|           %010"U32_F"          | (seq no)\n",
01267           ntohl(tcphdr->seqno)));
01268   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
01269   LWIP_DEBUGF(TCP_DEBUG, ("|           %010"U32_F"          | (ack no)\n",
01270          ntohl(tcphdr->ackno)));
01271   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
01272   LWIP_DEBUGF(TCP_DEBUG, ("| %2"U16_F" |   |%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"|     %5"U16_F"     | (hdrlen, flags (",
01273        TCPH_HDRLEN(tcphdr),
01274          TCPH_FLAGS(tcphdr) >> 5 & 1,
01275          TCPH_FLAGS(tcphdr) >> 4 & 1,
01276          TCPH_FLAGS(tcphdr) >> 3 & 1,
01277          TCPH_FLAGS(tcphdr) >> 2 & 1,
01278          TCPH_FLAGS(tcphdr) >> 1 & 1,
01279          TCPH_FLAGS(tcphdr) & 1,
01280          ntohs(tcphdr->wnd)));
01281   tcp_debug_print_flags(TCPH_FLAGS(tcphdr));
01282   LWIP_DEBUGF(TCP_DEBUG, ("), win)\n"));
01283   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
01284   LWIP_DEBUGF(TCP_DEBUG, ("|    0x%04"X16_F"     |     %5"U16_F"     | (chksum, urgp)\n",
01285          ntohs(tcphdr->chksum), ntohs(tcphdr->urgp)));
01286   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
01287 }
01288 
01289 /**
01290  * Print a tcp state for debugging purposes.
01291  *
01292  * @param s enum tcp_state to print
01293  */
01294 void
01295 tcp_debug_print_state(enum tcp_state s)
01296 {
01297   LWIP_DEBUGF(TCP_DEBUG, ("State: "));
01298   switch (s) {
01299   case CLOSED:
01300     LWIP_DEBUGF(TCP_DEBUG, ("CLOSED\n"));
01301     break;
01302  case LISTEN:
01303    LWIP_DEBUGF(TCP_DEBUG, ("LISTEN\n"));
01304    break;
01305   case SYN_SENT:
01306     LWIP_DEBUGF(TCP_DEBUG, ("SYN_SENT\n"));
01307     break;
01308   case SYN_RCVD:
01309     LWIP_DEBUGF(TCP_DEBUG, ("SYN_RCVD\n"));
01310     break;
01311   case ESTABLISHED:
01312     LWIP_DEBUGF(TCP_DEBUG, ("ESTABLISHED\n"));
01313     break;
01314   case FIN_WAIT_1:
01315     LWIP_DEBUGF(TCP_DEBUG, ("FIN_WAIT_1\n"));
01316     break;
01317   case FIN_WAIT_2:
01318     LWIP_DEBUGF(TCP_DEBUG, ("FIN_WAIT_2\n"));
01319     break;
01320   case CLOSE_WAIT:
01321     LWIP_DEBUGF(TCP_DEBUG, ("CLOSE_WAIT\n"));
01322     break;
01323   case CLOSING:
01324     LWIP_DEBUGF(TCP_DEBUG, ("CLOSING\n"));
01325     break;
01326   case LAST_ACK:
01327     LWIP_DEBUGF(TCP_DEBUG, ("LAST_ACK\n"));
01328     break;
01329   case TIME_WAIT:
01330     LWIP_DEBUGF(TCP_DEBUG, ("TIME_WAIT\n"));
01331    break;
01332   }
01333 }
01334 
01335 /**
01336  * Print tcp flags for debugging purposes.
01337  *
01338  * @param flags tcp flags, all active flags are printed
01339  */
01340 void
01341 tcp_debug_print_flags(u8_t flags)
01342 {
01343   if (flags & TCP_FIN) {
01344     LWIP_DEBUGF(TCP_DEBUG, ("FIN "));
01345   }
01346   if (flags & TCP_SYN) {
01347     LWIP_DEBUGF(TCP_DEBUG, ("SYN "));
01348   }
01349   if (flags & TCP_RST) {
01350     LWIP_DEBUGF(TCP_DEBUG, ("RST "));
01351   }
01352   if (flags & TCP_PSH) {
01353     LWIP_DEBUGF(TCP_DEBUG, ("PSH "));
01354   }
01355   if (flags & TCP_ACK) {
01356     LWIP_DEBUGF(TCP_DEBUG, ("ACK "));
01357   }
01358   if (flags & TCP_URG) {
01359     LWIP_DEBUGF(TCP_DEBUG, ("URG "));
01360   }
01361   if (flags & TCP_ECE) {
01362     LWIP_DEBUGF(TCP_DEBUG, ("ECE "));
01363   }
01364   if (flags & TCP_CWR) {
01365     LWIP_DEBUGF(TCP_DEBUG, ("CWR "));
01366   }
01367 }
01368 
01369 /**
01370  * Print all tcp_pcbs in every list for debugging purposes.
01371  */
01372 void
01373 tcp_debug_print_pcbs(void)
01374 {
01375   struct tcp_pcb *pcb;
01376   LWIP_DEBUGF(TCP_DEBUG, ("Active PCB states:\n"));
01377   for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
01378     LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
01379                        pcb->local_port, pcb->remote_port,
01380                        pcb->snd_nxt, pcb->rcv_nxt));
01381     tcp_debug_print_state(pcb->state);
01382   }    
01383   LWIP_DEBUGF(TCP_DEBUG, ("Listen PCB states:\n"));
01384   for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) {
01385     LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
01386                        pcb->local_port, pcb->remote_port,
01387                        pcb->snd_nxt, pcb->rcv_nxt));
01388     tcp_debug_print_state(pcb->state);
01389   }    
01390   LWIP_DEBUGF(TCP_DEBUG, ("TIME-WAIT PCB states:\n"));
01391   for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
01392     LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
01393                        pcb->local_port, pcb->remote_port,
01394                        pcb->snd_nxt, pcb->rcv_nxt));
01395     tcp_debug_print_state(pcb->state);
01396   }    
01397 }
01398 
01399 /**
01400  * Check state consistency of the tcp_pcb lists.
01401  */
01402 s16_t
01403 tcp_pcbs_sane(void)
01404 {
01405   struct tcp_pcb *pcb;
01406   for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
01407     LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != CLOSED", pcb->state != CLOSED);
01408     LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != LISTEN", pcb->state != LISTEN);
01409     LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
01410   }
01411   for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
01412     LWIP_ASSERT("tcp_pcbs_sane: tw pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
01413   }
01414   return 1;
01415 }
01416 #endif /* TCP_DEBUG */
01417 
01418 #endif /* LWIP_TCP */