Ethernet for Nucleo and Disco board STM32F746 works with gcc and arm. IAC is untested

Dependents:   STM32F746_iothub_client_sample_mqtt DISCO-F746NG_Ethernet Nucleo_F746ZG_Ethernet thethingsiO-DISCO_F746NG-mqtt ... 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 #include "lwip/tcp_impl.h"
00053 #include "lwip/debug.h"
00054 #include "lwip/stats.h"
00055 
00056 #include <string.h>
00057 
00058 #ifndef TCP_LOCAL_PORT_RANGE_START
00059 /* From http://www.iana.org/assignments/port-numbers:
00060    "The Dynamic and/or Private Ports are those from 49152 through 65535" */
00061 #define TCP_LOCAL_PORT_RANGE_START        0xc000
00062 #define TCP_LOCAL_PORT_RANGE_END          0xffff
00063 #define TCP_ENSURE_LOCAL_PORT_RANGE(port) (((port) & ~TCP_LOCAL_PORT_RANGE_START) + TCP_LOCAL_PORT_RANGE_START)
00064 #endif
00065 
00066 #if LWIP_TCP_KEEPALIVE
00067 #define TCP_KEEP_DUR(pcb)   ((pcb)->keep_cnt * (pcb)->keep_intvl)
00068 #define TCP_KEEP_INTVL(pcb) ((pcb)->keep_intvl)
00069 #else /* LWIP_TCP_KEEPALIVE */
00070 #define TCP_KEEP_DUR(pcb)   TCP_MAXIDLE
00071 #define TCP_KEEP_INTVL(pcb) TCP_KEEPINTVL_DEFAULT
00072 #endif /* LWIP_TCP_KEEPALIVE */
00073 
00074 const char * const tcp_state_str[] = {
00075   "CLOSED",
00076   "LISTEN",
00077   "SYN_SENT",
00078   "SYN_RCVD",
00079   "ESTABLISHED",
00080   "FIN_WAIT_1",
00081   "FIN_WAIT_2",
00082   "CLOSE_WAIT",
00083   "CLOSING",
00084   "LAST_ACK",
00085   "TIME_WAIT"
00086 };
00087 
00088 /* last local TCP port */
00089 static u16_t tcp_port = TCP_LOCAL_PORT_RANGE_START;
00090 static u16_t preloaded_tcp_port=0;
00091 
00092 /* Incremented every coarse grained timer shot (typically every 500 ms). */
00093 u32_t tcp_ticks;
00094 const u8_t tcp_backoff[13] =
00095     { 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7};
00096  /* Times per slowtmr hits */
00097 const u8_t tcp_persist_backoff[7] = { 3, 6, 12, 24, 48, 96, 120 };
00098 
00099 /* The TCP PCB lists. */
00100 
00101 /** List of all TCP PCBs bound but not yet (connected || listening) */
00102 struct tcp_pcb *tcp_bound_pcbs;
00103 /** List of all TCP PCBs in LISTEN state */
00104 union tcp_listen_pcbs_t tcp_listen_pcbs;
00105 /** List of all TCP PCBs that are in a state in which
00106  * they accept or send data. */
00107 struct tcp_pcb *tcp_active_pcbs;
00108 /** List of all TCP PCBs in TIME-WAIT state */
00109 struct tcp_pcb *tcp_tw_pcbs;
00110 
00111 #define NUM_TCP_PCB_LISTS               4
00112 #define NUM_TCP_PCB_LISTS_NO_TIME_WAIT  3
00113 /** An array with all (non-temporary) PCB lists, mainly used for smaller code size */
00114 struct tcp_pcb ** const tcp_pcb_lists[] = {&tcp_listen_pcbs.pcbs, &tcp_bound_pcbs,
00115   &tcp_active_pcbs, &tcp_tw_pcbs};
00116 
00117 /** Only used for temporary storage. */
00118 struct tcp_pcb *tcp_tmp_pcb;
00119 
00120 u8_t tcp_active_pcbs_changed;
00121 
00122 /** Timer counter to handle calling slow-timer from tcp_tmr() */
00123 static u8_t tcp_timer;
00124 static u8_t tcp_timer_ctr;
00125 static u16_t tcp_new_port(void);
00126 
00127 /**
00128  * Initialize this module.
00129  */
00130 void
00131 tcp_init(void)
00132 {
00133 #if LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND)
00134   tcp_port = TCP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND());
00135 #endif /* LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) */
00136 }
00137 
00138 /**
00139  * Called periodically to dispatch TCP timers.
00140  */
00141 void
00142 tcp_tmr(void)
00143 {
00144   /* Call tcp_fasttmr() every 250 ms */
00145   tcp_fasttmr();
00146 
00147   if (++tcp_timer & 1) {
00148     /* Call tcp_tmr() every 500 ms, i.e., every other timer
00149        tcp_tmr() is called. */
00150     tcp_slowtmr();
00151   }
00152 }
00153 
00154 /**
00155  * Closes the TX side of a connection held by the PCB.
00156  * For tcp_close(), a RST is sent if the application didn't receive all data
00157  * (tcp_recved() not called for all data passed to recv callback).
00158  *
00159  * Listening pcbs are freed and may not be referenced any more.
00160  * Connection pcbs are freed if not yet connected and may not be referenced
00161  * any more. If a connection is established (at least SYN received or in
00162  * a closing state), the connection is closed, and put in a closing state.
00163  * The pcb is then automatically freed in tcp_slowtmr(). It is therefore
00164  * unsafe to reference it.
00165  *
00166  * @param pcb the tcp_pcb to close
00167  * @return ERR_OK if connection has been closed
00168  *         another err_t if closing failed and pcb is not freed
00169  */
00170 static err_t
00171 tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data)
00172 {
00173   err_t err;
00174 
00175   if (rst_on_unacked_data && ((pcb->state == ESTABLISHED) || (pcb->state == CLOSE_WAIT))) {
00176     if ((pcb->refused_data != NULL) || (pcb->rcv_wnd != TCP_WND)) {
00177       /* Not all data received by application, send RST to tell the remote
00178          side about this. */
00179       LWIP_ASSERT("pcb->flags & TF_RXCLOSED", pcb->flags & TF_RXCLOSED);
00180 
00181       /* don't call tcp_abort here: we must not deallocate the pcb since
00182          that might not be expected when calling tcp_close */
00183       tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip,
00184         pcb->local_port, pcb->remote_port);
00185 
00186       tcp_pcb_purge(pcb);
00187       TCP_RMV_ACTIVE(pcb);
00188       if (pcb->state == ESTABLISHED) {
00189         /* move to TIME_WAIT since we close actively */
00190         pcb->state = TIME_WAIT;
00191         TCP_REG(&tcp_tw_pcbs, pcb);
00192       } else {
00193         /* CLOSE_WAIT: deallocate the pcb since we already sent a RST for it */
00194         memp_free(MEMP_TCP_PCB, pcb);
00195       }
00196       return ERR_OK;
00197     }
00198   }
00199 
00200   switch (pcb->state) {
00201   case CLOSED:
00202     /* Closing a pcb in the CLOSED state might seem erroneous,
00203      * however, it is in this state once allocated and as yet unused
00204      * and the user needs some way to free it should the need arise.
00205      * Calling tcp_close() with a pcb that has already been closed, (i.e. twice)
00206      * or for a pcb that has been used and then entered the CLOSED state
00207      * is erroneous, but this should never happen as the pcb has in those cases
00208      * been freed, and so any remaining handles are bogus. */
00209     err = ERR_OK;
00210     if (pcb->local_port != 0) {
00211       TCP_RMV(&tcp_bound_pcbs, pcb);
00212     }
00213     memp_free(MEMP_TCP_PCB, pcb);
00214     pcb = NULL;
00215     break;
00216   case LISTEN:
00217     err = ERR_OK;
00218     tcp_pcb_remove(&tcp_listen_pcbs.pcbs, pcb);
00219     memp_free(MEMP_TCP_PCB_LISTEN, pcb);
00220     pcb = NULL;
00221     break;
00222   case SYN_SENT:
00223     err = ERR_OK;
00224     TCP_PCB_REMOVE_ACTIVE(pcb);
00225     memp_free(MEMP_TCP_PCB, pcb);
00226     pcb = NULL;
00227     snmp_inc_tcpattemptfails();
00228     break;
00229   case SYN_RCVD:
00230     err = tcp_send_fin(pcb);
00231     if (err == ERR_OK) {
00232       snmp_inc_tcpattemptfails();
00233       pcb->state = FIN_WAIT_1;
00234     }
00235     break;
00236   case ESTABLISHED:
00237     err = tcp_send_fin(pcb);
00238     if (err == ERR_OK) {
00239       snmp_inc_tcpestabresets();
00240       pcb->state = FIN_WAIT_1;
00241     }
00242     break;
00243   case CLOSE_WAIT:
00244     err = tcp_send_fin(pcb);
00245     if (err == ERR_OK) {
00246       snmp_inc_tcpestabresets();
00247       pcb->state = LAST_ACK;
00248     }
00249     break;
00250   default:
00251     /* Has already been closed, do nothing. */
00252     err = ERR_OK;
00253     pcb = NULL;
00254     break;
00255   }
00256 
00257   if (pcb != NULL && err == ERR_OK) {
00258     /* To ensure all data has been sent when tcp_close returns, we have
00259        to make sure tcp_output doesn't fail.
00260        Since we don't really have to ensure all data has been sent when tcp_close
00261        returns (unsent data is sent from tcp timer functions, also), we don't care
00262        for the return value of tcp_output for now. */
00263     /* @todo: When implementing SO_LINGER, this must be changed somehow:
00264        If SOF_LINGER is set, the data should be sent and acked before close returns.
00265        This can only be valid for sequential APIs, not for the raw API. */
00266     tcp_output(pcb);
00267   }
00268   return err;
00269 }
00270 
00271 /**
00272  * Closes the connection held by the PCB.
00273  *
00274  * Listening pcbs are freed and may not be referenced any more.
00275  * Connection pcbs are freed if not yet connected and may not be referenced
00276  * any more. If a connection is established (at least SYN received or in
00277  * a closing state), the connection is closed, and put in a closing state.
00278  * The pcb is then automatically freed in tcp_slowtmr(). It is therefore
00279  * unsafe to reference it (unless an error is returned).
00280  *
00281  * @param pcb the tcp_pcb to close
00282  * @return ERR_OK if connection has been closed
00283  *         another err_t if closing failed and pcb is not freed
00284  */
00285 err_t
00286 tcp_close(struct tcp_pcb *pcb)
00287 {
00288 #if TCP_DEBUG
00289   LWIP_DEBUGF(TCP_DEBUG, ("tcp_close: closing in "));
00290   tcp_debug_print_state(pcb->state);
00291 #endif /* TCP_DEBUG */
00292 
00293   if (pcb->state != LISTEN) {
00294     /* Set a flag not to receive any more data... */
00295     pcb->flags |= TF_RXCLOSED;
00296   }
00297   /* ... and close */
00298   return tcp_close_shutdown(pcb, 1);
00299 }
00300 
00301 /**
00302  * Causes all or part of a full-duplex connection of this PCB to be shut down.
00303  * This doesn't deallocate the PCB unless shutting down both sides!
00304  * Shutting down both sides is the same as calling tcp_close, so if it succeds,
00305  * the PCB should not be referenced any more.
00306  *
00307  * @param pcb PCB to shutdown
00308  * @param shut_rx shut down receive side if this is != 0
00309  * @param shut_tx shut down send side if this is != 0
00310  * @return ERR_OK if shutdown succeeded (or the PCB has already been shut down)
00311  *         another err_t on error.
00312  */
00313 err_t
00314 tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx)
00315 {
00316   if (pcb->state == LISTEN) {
00317     return ERR_CONN;
00318   }
00319   if (shut_rx) {
00320     /* shut down the receive side: set a flag not to receive any more data... */
00321     pcb->flags |= TF_RXCLOSED;
00322     if (shut_tx) {
00323       /* shutting down the tx AND rx side is the same as closing for the raw API */
00324       return tcp_close_shutdown(pcb, 1);
00325     }
00326     /* ... and free buffered data */
00327     if (pcb->refused_data != NULL) {
00328       pbuf_free(pcb->refused_data);
00329       pcb->refused_data = NULL;
00330     }
00331   }
00332   if (shut_tx) {
00333     /* This can't happen twice since if it succeeds, the pcb's state is changed.
00334        Only close in these states as the others directly deallocate the PCB */
00335     switch (pcb->state) {
00336     case SYN_RCVD:
00337     case ESTABLISHED:
00338     case CLOSE_WAIT:
00339       return tcp_close_shutdown(pcb, shut_rx);
00340     default:
00341       /* Not (yet?) connected, cannot shutdown the TX side as that would bring us
00342         into CLOSED state, where the PCB is deallocated. */
00343       return ERR_CONN;
00344     }
00345   }
00346   return ERR_OK;
00347 }
00348 
00349 /**
00350  * Abandons a connection and optionally sends a RST to the remote
00351  * host.  Deletes the local protocol control block. This is done when
00352  * a connection is killed because of shortage of memory.
00353  *
00354  * @param pcb the tcp_pcb to abort
00355  * @param reset boolean to indicate whether a reset should be sent
00356  */
00357 void
00358 tcp_abandon(struct tcp_pcb *pcb, int reset)
00359 {
00360   u32_t seqno, ackno;
00361 #if LWIP_CALLBACK_API
00362   tcp_err_fn errf;
00363 #endif /* LWIP_CALLBACK_API */
00364   void *errf_arg;
00365 
00366   /* pcb->state LISTEN not allowed here */
00367   LWIP_ASSERT("don't call tcp_abort/tcp_abandon for listen-pcbs",
00368     pcb->state != LISTEN);
00369   /* Figure out on which TCP PCB list we are, and remove us. If we
00370      are in an active state, call the receive function associated with
00371      the PCB with a NULL argument, and send an RST to the remote end. */
00372   if (pcb->state == TIME_WAIT) {
00373     tcp_pcb_remove(&tcp_tw_pcbs, pcb);
00374     memp_free(MEMP_TCP_PCB, pcb);
00375   } else {
00376     seqno = pcb->snd_nxt;
00377     ackno = pcb->rcv_nxt;
00378 #if LWIP_CALLBACK_API
00379     errf = pcb->errf;
00380 #endif /* LWIP_CALLBACK_API */
00381     errf_arg = pcb->callback_arg;
00382     TCP_PCB_REMOVE_ACTIVE(pcb);
00383     if (pcb->unacked != NULL) {
00384       tcp_segs_free(pcb->unacked);
00385     }
00386     if (pcb->unsent != NULL) {
00387       tcp_segs_free(pcb->unsent);
00388     }
00389 #if TCP_QUEUE_OOSEQ
00390     if (pcb->ooseq != NULL) {
00391       tcp_segs_free(pcb->ooseq);
00392     }
00393 #endif /* TCP_QUEUE_OOSEQ */
00394     if (reset) {
00395       LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abandon: sending RST\n"));
00396       tcp_rst(seqno, ackno, &pcb->local_ip, &pcb->remote_ip, pcb->local_port, pcb->remote_port);
00397     }
00398     memp_free(MEMP_TCP_PCB, pcb);
00399     TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT);
00400   }
00401 }
00402 
00403 /**
00404  * Aborts the connection by sending a RST (reset) segment to the remote
00405  * host. The pcb is deallocated. This function never fails.
00406  *
00407  * ATTENTION: When calling this from one of the TCP callbacks, make
00408  * sure you always return ERR_ABRT (and never return ERR_ABRT otherwise
00409  * or you will risk accessing deallocated memory or memory leaks!
00410  *
00411  * @param pcb the tcp pcb to abort
00412  */
00413 void
00414 tcp_abort(struct tcp_pcb *pcb)
00415 {
00416   tcp_abandon(pcb, 1);
00417 }
00418 
00419 /**
00420  * Binds the connection to a local portnumber and IP address. If the
00421  * IP address is not given (i.e., ipaddr == NULL), the IP address of
00422  * the outgoing network interface is used instead.
00423  *
00424  * @param pcb the tcp_pcb to bind (no check is done whether this pcb is
00425  *        already bound!)
00426  * @param ipaddr the local ip address to bind to (use IP_ADDR_ANY to bind
00427  *        to any local address
00428  * @param port the local port to bind to
00429  * @return ERR_USE if the port is already in use
00430  *         ERR_VAL if bind failed because the PCB is not in a valid state
00431  *         ERR_OK if bound
00432  */
00433 err_t
00434 tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port)
00435 {
00436   int i;
00437   int max_pcb_list = NUM_TCP_PCB_LISTS;
00438   struct tcp_pcb *cpcb;
00439 
00440   LWIP_ERROR("tcp_bind: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_VAL);
00441 
00442 #if SO_REUSE
00443   /* Unless the REUSEADDR flag is set,
00444      we have to check the pcbs in TIME-WAIT state, also.
00445      We do not dump TIME_WAIT pcb's; they can still be matched by incoming
00446      packets using both local and remote IP addresses and ports to distinguish.
00447    */
00448   if (ip_get_option(pcb, SOF_REUSEADDR)) {
00449     max_pcb_list = NUM_TCP_PCB_LISTS_NO_TIME_WAIT;
00450   }
00451 #endif /* SO_REUSE */
00452 
00453   if (port == 0) {
00454     port = tcp_new_port();
00455     if (port == 0) {
00456       return ERR_BUF;
00457     }
00458   }
00459 
00460   /* Check if the address already is in use (on all lists) */
00461   for (i = 0; i < max_pcb_list; i++) {
00462     for(cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) {
00463       if (cpcb->local_port == port) {
00464 #if SO_REUSE
00465         /* Omit checking for the same port if both pcbs have REUSEADDR set.
00466            For SO_REUSEADDR, the duplicate-check for a 5-tuple is done in
00467            tcp_connect. */
00468         if (!ip_get_option(pcb, SOF_REUSEADDR) ||
00469             !ip_get_option(cpcb, SOF_REUSEADDR))
00470 #endif /* SO_REUSE */
00471         {
00472           if (ip_addr_isany(&(cpcb->local_ip)) ||
00473               ip_addr_isany(ipaddr) ||
00474               ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {
00475             return ERR_USE;
00476           }
00477         }
00478       }
00479     }
00480   }
00481 
00482   if (!ip_addr_isany(ipaddr)) {
00483     pcb->local_ip = *ipaddr;
00484   }
00485   pcb->local_port = port;
00486   TCP_REG(&tcp_bound_pcbs, pcb);
00487   LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %"U16_F"\n", port));
00488   return ERR_OK;
00489 }
00490 #if LWIP_CALLBACK_API
00491 /**
00492  * Default accept callback if no accept callback is specified by the user.
00493  */
00494 static err_t
00495 tcp_accept_null(void *arg, struct tcp_pcb *pcb, err_t err)
00496 {
00497   LWIP_UNUSED_ARG(arg);
00498   LWIP_UNUSED_ARG(pcb);
00499   LWIP_UNUSED_ARG(err);
00500 
00501   return ERR_ABRT;
00502 }
00503 #endif /* LWIP_CALLBACK_API */
00504 
00505 /**
00506  * Set the state of the connection to be LISTEN, which means that it
00507  * is able to accept incoming connections. The protocol control block
00508  * is reallocated in order to consume less memory. Setting the
00509  * connection to LISTEN is an irreversible process.
00510  *
00511  * @param pcb the original tcp_pcb
00512  * @param backlog the incoming connections queue limit
00513  * @return tcp_pcb used for listening, consumes less memory.
00514  *
00515  * @note The original tcp_pcb is freed. This function therefore has to be
00516  *       called like this:
00517  *             tpcb = tcp_listen(tpcb);
00518  */
00519 struct tcp_pcb *
00520 tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
00521 {
00522   struct tcp_pcb_listen *lpcb;
00523 
00524   LWIP_UNUSED_ARG(backlog);
00525   LWIP_ERROR("tcp_listen: pcb already connected", pcb->state == CLOSED, return NULL);
00526 
00527   /* already listening? */
00528   if (pcb->state == LISTEN) {
00529     return pcb;
00530   }
00531 #if SO_REUSE
00532   if (ip_get_option(pcb, SOF_REUSEADDR)) {
00533     /* Since SOF_REUSEADDR allows reusing a local address before the pcb's usage
00534        is declared (listen-/connection-pcb), we have to make sure now that
00535        this port is only used once for every local IP. */
00536     for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
00537       if (lpcb->local_port == pcb->local_port) {
00538         if (ip_addr_cmp(&lpcb->local_ip, &pcb->local_ip)) {
00539           /* this address/port is already used */
00540           return NULL;
00541         }
00542       }
00543     }
00544   }
00545 #endif /* SO_REUSE */
00546   lpcb = (struct tcp_pcb_listen *)memp_malloc(MEMP_TCP_PCB_LISTEN);
00547   if (lpcb == NULL) {
00548     return NULL;
00549   }
00550   lpcb->callback_arg = pcb->callback_arg;
00551   lpcb->local_port = pcb->local_port;
00552   lpcb->state = LISTEN;
00553   lpcb->prio = pcb->prio;
00554   lpcb->so_options = pcb->so_options;
00555   ip_set_option(lpcb, SOF_ACCEPTCONN);
00556   lpcb->ttl = pcb->ttl;
00557   lpcb->tos = pcb->tos;
00558   ip_addr_copy(lpcb->local_ip, pcb->local_ip);
00559   if (pcb->local_port != 0) {
00560     TCP_RMV(&tcp_bound_pcbs, pcb);
00561   }
00562   memp_free(MEMP_TCP_PCB, pcb);
00563 #if LWIP_CALLBACK_API
00564   lpcb->accept = tcp_accept_null;
00565 #endif /* LWIP_CALLBACK_API */
00566 #if TCP_LISTEN_BACKLOG
00567   lpcb->accepts_pending = 0;
00568   lpcb->backlog = (backlog ? backlog : 1);
00569 #endif /* TCP_LISTEN_BACKLOG */
00570   TCP_REG(&tcp_listen_pcbs.pcbs, (struct tcp_pcb *)lpcb);
00571   return (struct tcp_pcb *)lpcb;
00572 }
00573 
00574 /**
00575  * Update the state that tracks the available window space to advertise.
00576  *
00577  * Returns how much extra window would be advertised if we sent an
00578  * update now.
00579  */
00580 u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb)
00581 {
00582   u32_t new_right_edge = pcb->rcv_nxt + pcb->rcv_wnd;
00583 
00584   if (TCP_SEQ_GEQ(new_right_edge, pcb->rcv_ann_right_edge + LWIP_MIN((TCP_WND / 2), pcb->mss))) {
00585     /* we can advertise more window */
00586     pcb->rcv_ann_wnd = pcb->rcv_wnd;
00587     return new_right_edge - pcb->rcv_ann_right_edge;
00588   } else {
00589     if (TCP_SEQ_GT(pcb->rcv_nxt, pcb->rcv_ann_right_edge)) {
00590       /* Can happen due to other end sending out of advertised window,
00591        * but within actual available (but not yet advertised) window */
00592       pcb->rcv_ann_wnd = 0;
00593     } else {
00594       /* keep the right edge of window constant */
00595       u32_t new_rcv_ann_wnd = pcb->rcv_ann_right_edge - pcb->rcv_nxt;
00596       LWIP_ASSERT("new_rcv_ann_wnd <= 0xffff", new_rcv_ann_wnd <= 0xffff);
00597       pcb->rcv_ann_wnd = (u16_t)new_rcv_ann_wnd;
00598     }
00599     return 0;
00600   }
00601 }
00602 
00603 /**
00604  * This function should be called by the application when it has
00605  * processed the data. The purpose is to advertise a larger window
00606  * when the data has been processed.
00607  *
00608  * @param pcb the tcp_pcb for which data is read
00609  * @param len the amount of bytes that have been read by the application
00610  */
00611 void
00612 tcp_recved(struct tcp_pcb *pcb, u16_t len)
00613 {
00614   int wnd_inflation;
00615 
00616   /* pcb->state LISTEN not allowed here */
00617   LWIP_ASSERT("don't call tcp_recved for listen-pcbs",
00618     pcb->state != LISTEN);
00619   LWIP_ASSERT("tcp_recved: len would wrap rcv_wnd\n",
00620               len <= 0xffff - pcb->rcv_wnd );
00621 
00622   pcb->rcv_wnd += len;
00623   if (pcb->rcv_wnd > TCP_WND) {
00624     pcb->rcv_wnd = TCP_WND;
00625   }
00626 
00627   wnd_inflation = tcp_update_rcv_ann_wnd(pcb);
00628 
00629   /* If the change in the right edge of window is significant (default
00630    * watermark is TCP_WND/4), then send an explicit update now.
00631    * Otherwise wait for a packet to be sent in the normal course of
00632    * events (or more window to be available later) */
00633   if (wnd_inflation >= TCP_WND_UPDATE_THRESHOLD) {
00634     tcp_ack_now(pcb);
00635     tcp_output(pcb);
00636   }
00637 
00638   LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: recveived %"U16_F" bytes, wnd %"U16_F" (%"U16_F").\n",
00639          len, pcb->rcv_wnd, TCP_WND - pcb->rcv_wnd));
00640 }
00641 /**
00642 * Preselect a tcp_port for next use
00643 * e.g. as source port
00644 */
00645 void tcp_preselect_port(u16_t port)
00646 {
00647     preloaded_tcp_port=port;
00648     return;
00649 }
00650 
00651 
00652 
00653 /**
00654  * Allocate a new local TCP port.
00655  *
00656  * @return a new (free) local TCP port number
00657  */
00658 static u16_t
00659 tcp_new_port(void)
00660 {
00661   u8_t i;
00662   u16_t n = 0;
00663   struct tcp_pcb *pcb;
00664   if (preloaded_tcp_port!=0)
00665   {
00666       n=preloaded_tcp_port;
00667       preloaded_tcp_port=0;
00668       return n;
00669   }
00670 again:
00671   if (tcp_port++ == TCP_LOCAL_PORT_RANGE_END) {
00672     tcp_port = TCP_LOCAL_PORT_RANGE_START;
00673   }
00674   /* Check all PCB lists. */
00675   for (i = 0; i < NUM_TCP_PCB_LISTS; i++) {
00676     for(pcb = *tcp_pcb_lists[i]; pcb != NULL; pcb = pcb->next) {
00677       if (pcb->local_port == tcp_port) {
00678         if (++n > (TCP_LOCAL_PORT_RANGE_END - TCP_LOCAL_PORT_RANGE_START)) {
00679           return 0;
00680         }
00681         goto again;
00682       }
00683     }
00684   }
00685   return tcp_port;
00686 }
00687 
00688 /**
00689  * Connects to another host. The function given as the "connected"
00690  * argument will be called when the connection has been established.
00691  *
00692  * @param pcb the tcp_pcb used to establish the connection
00693  * @param ipaddr the remote ip address to connect to
00694  * @param port the remote tcp port to connect to
00695  * @param connected callback function to call when connected (or on error)
00696  * @return ERR_VAL if invalid arguments are given
00697  *         ERR_OK if connect request has been sent
00698  *         other err_t values if connect request couldn't be sent
00699  */
00700 err_t
00701 tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port,
00702       tcp_connected_fn connected)
00703 {
00704   err_t ret;
00705   u32_t iss;
00706   u16_t old_local_port;
00707 
00708   LWIP_ERROR("tcp_connect: can only connect from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN);
00709 
00710   LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port));
00711   if (ipaddr != NULL) {
00712     pcb->remote_ip = *ipaddr;
00713   } else {
00714     return ERR_VAL;
00715   }
00716   pcb->remote_port = port;
00717 
00718   /* check if we have a route to the remote host */
00719   if (ip_addr_isany(&(pcb->local_ip))) {
00720     /* no local IP address set, yet. */
00721     struct netif *netif = ip_route(&(pcb->remote_ip));
00722     if (netif == NULL) {
00723       /* Don't even try to send a SYN packet if we have no route
00724          since that will fail. */
00725       return ERR_RTE;
00726     }
00727     /* Use the netif's IP address as local address. */
00728     ip_addr_copy(pcb->local_ip, netif->ip_addr);
00729   }
00730 
00731   old_local_port = pcb->local_port;
00732   if (pcb->local_port == 0) {
00733     pcb->local_port = tcp_new_port();
00734     if (pcb->local_port == 0) {
00735       return ERR_BUF;
00736     }
00737   }
00738 #if SO_REUSE
00739   if (ip_get_option(pcb, SOF_REUSEADDR)) {
00740     /* Since SOF_REUSEADDR allows reusing a local address, we have to make sure
00741        now that the 5-tuple is unique. */
00742     struct tcp_pcb *cpcb;
00743     int i;
00744     /* Don't check listen- and bound-PCBs, check active- and TIME-WAIT PCBs. */
00745     for (i = 2; i < NUM_TCP_PCB_LISTS; i++) {
00746       for(cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) {
00747         if ((cpcb->local_port == pcb->local_port) &&
00748             (cpcb->remote_port == port) &&
00749             ip_addr_cmp(&cpcb->local_ip, &pcb->local_ip) &&
00750             ip_addr_cmp(&cpcb->remote_ip, ipaddr)) {
00751           /* linux returns EISCONN here, but ERR_USE should be OK for us */
00752           return ERR_USE;
00753         }
00754       }
00755     }
00756   }
00757 #endif /* SO_REUSE */
00758   iss = tcp_next_iss();
00759   pcb->rcv_nxt = 0;
00760   pcb->snd_nxt = iss;
00761   pcb->lastack = iss - 1;
00762   pcb->snd_lbb = iss - 1;
00763   pcb->rcv_wnd = TCP_WND;
00764   pcb->rcv_ann_wnd = TCP_WND;
00765   pcb->rcv_ann_right_edge = pcb->rcv_nxt;
00766   pcb->snd_wnd = TCP_WND;
00767   /* As initial send MSS, we use TCP_MSS but limit it to 536.
00768      The send MSS is updated when an MSS option is received. */
00769   pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS;
00770 #if TCP_CALCULATE_EFF_SEND_MSS
00771   pcb->mss = tcp_eff_send_mss(pcb->mss, ipaddr);
00772 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
00773   pcb->cwnd = 1;
00774   pcb->ssthresh = pcb->mss * 10;
00775 #if LWIP_CALLBACK_API
00776   pcb->connected = connected;
00777 #else /* LWIP_CALLBACK_API */
00778   LWIP_UNUSED_ARG(connected);
00779 #endif /* LWIP_CALLBACK_API */
00780 
00781   /* Send a SYN together with the MSS option. */
00782   ret = tcp_enqueue_flags(pcb, TCP_SYN);
00783   if (ret == ERR_OK) {
00784     /* SYN segment was enqueued, changed the pcbs state now */
00785     pcb->state = SYN_SENT;
00786     if (old_local_port != 0) {
00787       TCP_RMV(&tcp_bound_pcbs, pcb);
00788     }
00789     TCP_REG_ACTIVE(pcb);
00790     snmp_inc_tcpactiveopens();
00791 
00792     tcp_output(pcb);
00793   }
00794   return ret;
00795 }
00796 
00797 /**
00798  * Called every 500 ms and implements the retransmission timer and the timer that
00799  * removes PCBs that have been in TIME-WAIT for enough time. It also increments
00800  * various timers such as the inactivity timer in each PCB.
00801  *
00802  * Automatically called from tcp_tmr().
00803  */
00804 void
00805 tcp_slowtmr(void)
00806 {
00807   struct tcp_pcb *pcb, *prev;
00808   u16_t eff_wnd;
00809   u8_t pcb_remove;      /* flag if a PCB should be removed */
00810   u8_t pcb_reset;       /* flag if a RST should be sent when removing */
00811   err_t err;
00812 
00813   err = ERR_OK;
00814 
00815   ++tcp_ticks;
00816   ++tcp_timer_ctr;
00817 
00818 tcp_slowtmr_start:
00819   /* Steps through all of the active PCBs. */
00820   prev = NULL;
00821   pcb = tcp_active_pcbs;
00822   if (pcb == NULL) {
00823     LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n"));
00824   }
00825   while (pcb != NULL) {
00826     LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb\n"));
00827     LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED);
00828     LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN);
00829     LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT);
00830     if (pcb->last_timer == tcp_timer_ctr) {
00831       /* skip this pcb, we have already processed it */
00832       pcb = pcb->next;
00833       continue;
00834     }
00835     pcb->last_timer = tcp_timer_ctr;
00836 
00837     pcb_remove = 0;
00838     pcb_reset = 0;
00839 
00840     if (pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) {
00841       ++pcb_remove;
00842       LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n"));
00843     }
00844     else if (pcb->nrtx == TCP_MAXRTX) {
00845       ++pcb_remove;
00846       LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n"));
00847     } else {
00848       if (pcb->persist_backoff > 0) {
00849         /* If snd_wnd is zero, use persist timer to send 1 byte probes
00850          * instead of using the standard retransmission mechanism. */
00851         pcb->persist_cnt++;
00852         if (pcb->persist_cnt >= tcp_persist_backoff[pcb->persist_backoff-1]) {
00853           pcb->persist_cnt = 0;
00854           if (pcb->persist_backoff < sizeof(tcp_persist_backoff)) {
00855             pcb->persist_backoff++;
00856           }
00857           tcp_zero_window_probe(pcb);
00858         }
00859       } else {
00860         /* Increase the retransmission timer if it is running */
00861         if(pcb->rtime >= 0) {
00862           ++pcb->rtime;
00863         }
00864 
00865         if (pcb->unacked != NULL && pcb->rtime >= pcb->rto) {
00866           /* Time for a retransmission. */
00867           LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %"S16_F
00868                                       " pcb->rto %"S16_F"\n",
00869                                       pcb->rtime, pcb->rto));
00870 
00871           /* Double retransmission time-out unless we are trying to
00872            * connect to somebody (i.e., we are in SYN_SENT). */
00873           if (pcb->state != SYN_SENT) {
00874             pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx];
00875           }
00876 
00877           /* Reset the retransmission timer. */
00878           pcb->rtime = 0;
00879 
00880           /* Reduce congestion window and ssthresh. */
00881           eff_wnd = LWIP_MIN(pcb->cwnd, pcb->snd_wnd);
00882           pcb->ssthresh = eff_wnd >> 1;
00883           if (pcb->ssthresh < (pcb->mss << 1)) {
00884             pcb->ssthresh = (pcb->mss << 1);
00885           }
00886           pcb->cwnd = pcb->mss;
00887           LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: cwnd %"U16_F
00888                                        " ssthresh %"U16_F"\n",
00889                                        pcb->cwnd, pcb->ssthresh));
00890 
00891           /* The following needs to be called AFTER cwnd is set to one
00892              mss - STJ */
00893           tcp_rexmit_rto(pcb);
00894         }
00895       }
00896     }
00897     /* Check if this PCB has stayed too long in FIN-WAIT-2 */
00898     if (pcb->state == FIN_WAIT_2) {
00899       /* If this PCB is in FIN_WAIT_2 because of SHUT_WR don't let it time out. */
00900       if (pcb->flags & TF_RXCLOSED) {
00901         /* PCB was fully closed (either through close() or SHUT_RDWR):
00902            normal FIN-WAIT timeout handling. */
00903         if ((u32_t)(tcp_ticks - pcb->tmr) >
00904             TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) {
00905           ++pcb_remove;
00906           LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n"));
00907         }
00908       }
00909     }
00910 
00911     /* Check if KEEPALIVE should be sent */
00912     if(ip_get_option(pcb, SOF_KEEPALIVE) &&
00913        ((pcb->state == ESTABLISHED) ||
00914         (pcb->state == CLOSE_WAIT))) {
00915       if((u32_t)(tcp_ticks - pcb->tmr) >
00916          (pcb->keep_idle + TCP_KEEP_DUR(pcb)) / TCP_SLOW_INTERVAL)
00917       {
00918         LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to %"U16_F".%"U16_F".%"U16_F".%"U16_F".\n",
00919                                 ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip),
00920                                 ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip)));
00921 
00922         ++pcb_remove;
00923         ++pcb_reset;
00924       }
00925       else if((u32_t)(tcp_ticks - pcb->tmr) >
00926               (pcb->keep_idle + pcb->keep_cnt_sent * TCP_KEEP_INTVL(pcb))
00927               / TCP_SLOW_INTERVAL)
00928       {
00929         tcp_keepalive(pcb);
00930         pcb->keep_cnt_sent++;
00931       }
00932     }
00933 
00934     /* If this PCB has queued out of sequence data, but has been
00935        inactive for too long, will drop the data (it will eventually
00936        be retransmitted). */
00937 #if TCP_QUEUE_OOSEQ
00938     if (pcb->ooseq != NULL &&
00939         (u32_t)tcp_ticks - pcb->tmr >= pcb->rto * TCP_OOSEQ_TIMEOUT) {
00940       tcp_segs_free(pcb->ooseq);
00941       pcb->ooseq = NULL;
00942       LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: dropping OOSEQ queued data\n"));
00943     }
00944 #endif /* TCP_QUEUE_OOSEQ */
00945 
00946     /* Check if this PCB has stayed too long in SYN-RCVD */
00947     if (pcb->state == SYN_RCVD) {
00948       if ((u32_t)(tcp_ticks - pcb->tmr) >
00949           TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) {
00950         ++pcb_remove;
00951         LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n"));
00952       }
00953     }
00954 
00955     /* Check if this PCB has stayed too long in LAST-ACK */
00956     if (pcb->state == LAST_ACK) {
00957       if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {
00958         ++pcb_remove;
00959         LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in LAST-ACK\n"));
00960       }
00961     }
00962 
00963     /* If the PCB should be removed, do it. */
00964     if (pcb_remove) {
00965       struct tcp_pcb *pcb2;
00966       tcp_err_fn err_fn;
00967       void *err_arg;
00968       tcp_pcb_purge(pcb);
00969       /* Remove PCB from tcp_active_pcbs list. */
00970       if (prev != NULL) {
00971         LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs);
00972         prev->next = pcb->next;
00973       } else {
00974         /* This PCB was the first. */
00975         LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb);
00976         tcp_active_pcbs = pcb->next;
00977       }
00978 
00979       if (pcb_reset) {
00980         tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip,
00981           pcb->local_port, pcb->remote_port);
00982       }
00983 
00984       err_fn = pcb->errf;
00985       err_arg = pcb->callback_arg;
00986       pcb2 = pcb;
00987       pcb = pcb->next;
00988       memp_free(MEMP_TCP_PCB, pcb2);
00989 
00990       tcp_active_pcbs_changed = 0;
00991       TCP_EVENT_ERR(err_fn, err_arg, ERR_ABRT);
00992       if (tcp_active_pcbs_changed) {
00993         goto tcp_slowtmr_start;
00994       }
00995     } else {
00996       /* get the 'next' element now and work with 'prev' below (in case of abort) */
00997       prev = pcb;
00998       pcb = pcb->next;
00999 
01000       /* We check if we should poll the connection. */
01001       ++prev->polltmr;
01002       if (prev->polltmr >= prev->pollinterval) {
01003         prev->polltmr = 0;
01004         LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n"));
01005         tcp_active_pcbs_changed = 0;
01006         TCP_EVENT_POLL(prev, err);
01007         if (tcp_active_pcbs_changed) {
01008           goto tcp_slowtmr_start;
01009         }
01010         /* if err == ERR_ABRT, 'prev' is already deallocated */
01011         if (err == ERR_OK) {
01012           tcp_output(prev);
01013         }
01014       }
01015     }
01016   }
01017 
01018 
01019   /* Steps through all of the TIME-WAIT PCBs. */
01020   prev = NULL;
01021   pcb = tcp_tw_pcbs;
01022   while (pcb != NULL) {
01023     LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
01024     pcb_remove = 0;
01025 
01026     /* Check if this PCB has stayed long enough in TIME-WAIT */
01027     if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {
01028       ++pcb_remove;
01029     }
01030 
01031 
01032 
01033     /* If the PCB should be removed, do it. */
01034     if (pcb_remove) {
01035       struct tcp_pcb *pcb2;
01036       tcp_pcb_purge(pcb);
01037       /* Remove PCB from tcp_tw_pcbs list. */
01038       if (prev != NULL) {
01039         LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs);
01040         prev->next = pcb->next;
01041       } else {
01042         /* This PCB was the first. */
01043         LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb);
01044         tcp_tw_pcbs = pcb->next;
01045       }
01046       pcb2 = pcb;
01047       pcb = pcb->next;
01048       memp_free(MEMP_TCP_PCB, pcb2);
01049     } else {
01050       prev = pcb;
01051       pcb = pcb->next;
01052     }
01053   }
01054 }
01055 
01056 /**
01057  * Is called every TCP_FAST_INTERVAL (250 ms) and process data previously
01058  * "refused" by upper layer (application) and sends delayed ACKs.
01059  *
01060  * Automatically called from tcp_tmr().
01061  */
01062 void
01063 tcp_fasttmr(void)
01064 {
01065   struct tcp_pcb *pcb;
01066 
01067   ++tcp_timer_ctr;
01068 
01069 tcp_fasttmr_start:
01070   pcb = tcp_active_pcbs;
01071 
01072   while(pcb != NULL) {
01073     if (pcb->last_timer != tcp_timer_ctr) {
01074       struct tcp_pcb *next;
01075       pcb->last_timer = tcp_timer_ctr;
01076       /* send delayed ACKs */
01077       if (pcb->flags & TF_ACK_DELAY) {
01078         LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n"));
01079         tcp_ack_now(pcb);
01080         tcp_output(pcb);
01081         pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
01082       }
01083 
01084       next = pcb->next;
01085 
01086       /* If there is data which was previously "refused" by upper layer */
01087       if (pcb->refused_data != NULL) {
01088         tcp_active_pcbs_changed = 0;
01089         tcp_process_refused_data(pcb);
01090         if (tcp_active_pcbs_changed) {
01091           /* application callback has changed the pcb list: restart the loop */
01092           goto tcp_fasttmr_start;
01093         }
01094       }
01095       pcb = next;
01096     }
01097   }
01098 }
01099 
01100 /** Pass pcb->refused_data to the recv callback */
01101 err_t
01102 tcp_process_refused_data(struct tcp_pcb *pcb)
01103 {
01104   err_t err;
01105   u8_t refused_flags = pcb->refused_data->flags;
01106   /* set pcb->refused_data to NULL in case the callback frees it and then
01107      closes the pcb */
01108   struct pbuf *refused_data = pcb->refused_data;
01109   pcb->refused_data = NULL;
01110   /* Notify again application with data previously received. */
01111   LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: notify kept packet\n"));
01112   TCP_EVENT_RECV(pcb, refused_data, ERR_OK, err);
01113   if (err == ERR_OK) {
01114     /* did refused_data include a FIN? */
01115     if (refused_flags & PBUF_FLAG_TCP_FIN) {
01116       /* correct rcv_wnd as the application won't call tcp_recved()
01117          for the FIN's seqno */
01118       if (pcb->rcv_wnd != TCP_WND) {
01119         pcb->rcv_wnd++;
01120       }
01121       TCP_EVENT_CLOSED(pcb, err);
01122       if (err == ERR_ABRT) {
01123         return ERR_ABRT;
01124       }
01125     }
01126   } else if (err == ERR_ABRT) {
01127     /* if err == ERR_ABRT, 'pcb' is already deallocated */
01128     /* Drop incoming packets because pcb is "full" (only if the incoming
01129        segment contains data). */
01130     LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n"));
01131     return ERR_ABRT;
01132   } else {
01133     /* data is still refused, pbuf is still valid (go on for ACK-only packets) */
01134     pcb->refused_data = refused_data;
01135   }
01136   return ERR_OK;
01137 }
01138 
01139 /**
01140  * Deallocates a list of TCP segments (tcp_seg structures).
01141  *
01142  * @param seg tcp_seg list of TCP segments to free
01143  */
01144 void
01145 tcp_segs_free(struct tcp_seg *seg)
01146 {
01147   while (seg != NULL) {
01148     struct tcp_seg *next = seg->next;
01149     tcp_seg_free(seg);
01150     seg = next;
01151   }
01152 }
01153 
01154 /**
01155  * Frees a TCP segment (tcp_seg structure).
01156  *
01157  * @param seg single tcp_seg to free
01158  */
01159 void
01160 tcp_seg_free(struct tcp_seg *seg)
01161 {
01162   if (seg != NULL) {
01163     if (seg->p != NULL) {
01164       pbuf_free(seg->p);
01165 #if TCP_DEBUG
01166       seg->p = NULL;
01167 #endif /* TCP_DEBUG */
01168     }
01169     memp_free(MEMP_TCP_SEG, seg);
01170   }
01171 }
01172 
01173 /**
01174  * Sets the priority of a connection.
01175  *
01176  * @param pcb the tcp_pcb to manipulate
01177  * @param prio new priority
01178  */
01179 void
01180 tcp_setprio(struct tcp_pcb *pcb, u8_t prio)
01181 {
01182   pcb->prio = prio;
01183 }
01184 
01185 #if TCP_QUEUE_OOSEQ
01186 /**
01187  * Returns a copy of the given TCP segment.
01188  * The pbuf and data are not copied, only the pointers
01189  *
01190  * @param seg the old tcp_seg
01191  * @return a copy of seg
01192  */
01193 struct tcp_seg *
01194 tcp_seg_copy(struct tcp_seg *seg)
01195 {
01196   struct tcp_seg *cseg;
01197 
01198   cseg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG);
01199   if (cseg == NULL) {
01200     return NULL;
01201   }
01202   SMEMCPY((u8_t *)cseg, (const u8_t *)seg, sizeof(struct tcp_seg));
01203   pbuf_ref(cseg->p);
01204   return cseg;
01205 }
01206 #endif /* TCP_QUEUE_OOSEQ */
01207 
01208 #if LWIP_CALLBACK_API
01209 /**
01210  * Default receive callback that is called if the user didn't register
01211  * a recv callback for the pcb.
01212  */
01213 err_t
01214 tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
01215 {
01216   LWIP_UNUSED_ARG(arg);
01217   if (p != NULL) {
01218     tcp_recved(pcb, p->tot_len);
01219     pbuf_free(p);
01220   } else if (err == ERR_OK) {
01221     return tcp_close(pcb);
01222   }
01223   return ERR_OK;
01224 }
01225 #endif /* LWIP_CALLBACK_API */
01226 
01227 /**
01228  * Kills the oldest active connection that has the same or lower priority than
01229  * 'prio'.
01230  *
01231  * @param prio minimum priority
01232  */
01233 static void
01234 tcp_kill_prio(u8_t prio)
01235 {
01236   struct tcp_pcb *pcb, *inactive;
01237   u32_t inactivity;
01238   u8_t mprio;
01239 
01240 
01241   mprio = TCP_PRIO_MAX;
01242 
01243   /* We kill the oldest active connection that has lower priority than prio. */
01244   inactivity = 0;
01245   inactive = NULL;
01246   for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
01247     if (pcb->prio <= prio &&
01248        pcb->prio <= mprio &&
01249        (u32_t)(tcp_ticks - pcb->tmr) >= inactivity) {
01250       inactivity = tcp_ticks - pcb->tmr;
01251       inactive = pcb;
01252       mprio = pcb->prio;
01253     }
01254   }
01255   if (inactive != NULL) {
01256     LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB %p (%"S32_F")\n",
01257            (void *)inactive, inactivity));
01258     tcp_abort(inactive);
01259   }
01260 }
01261 
01262 /**
01263  * Kills the oldest connection that is in TIME_WAIT state.
01264  * Called from tcp_alloc() if no more connections are available.
01265  */
01266 static void
01267 tcp_kill_timewait(void)
01268 {
01269   struct tcp_pcb *pcb, *inactive;
01270   u32_t inactivity;
01271 
01272   inactivity = 0;
01273   inactive = NULL;
01274   /* Go through the list of TIME_WAIT pcbs and get the oldest pcb. */
01275   for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
01276     if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) {
01277       inactivity = tcp_ticks - pcb->tmr;
01278       inactive = pcb;
01279     }
01280   }
01281   if (inactive != NULL) {
01282     LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB %p (%"S32_F")\n",
01283            (void *)inactive, inactivity));
01284     tcp_abort(inactive);
01285   }
01286 }
01287 
01288 /**
01289  * Allocate a new tcp_pcb structure.
01290  *
01291  * @param prio priority for the new pcb
01292  * @return a new tcp_pcb that initially is in state CLOSED
01293  */
01294 struct tcp_pcb *
01295 tcp_alloc(u8_t prio)
01296 {
01297   struct tcp_pcb *pcb;
01298   u32_t iss;
01299 
01300   pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
01301   if (pcb == NULL) {
01302     /* Try killing oldest connection in TIME-WAIT. */
01303     LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest TIME-WAIT connection\n"));
01304     tcp_kill_timewait();
01305     /* Try to allocate a tcp_pcb again. */
01306     pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
01307     if (pcb == NULL) {
01308       /* Try killing active connections with lower priority than the new one. */
01309       LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing connection with prio lower than %d\n", prio));
01310       tcp_kill_prio(prio);
01311       /* Try to allocate a tcp_pcb again. */
01312       pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
01313       if (pcb != NULL) {
01314         /* adjust err stats: memp_malloc failed twice before */
01315         MEMP_STATS_DEC(err, MEMP_TCP_PCB);
01316       }
01317     }
01318     if (pcb != NULL) {
01319       /* adjust err stats: timewait PCB was freed above */
01320       MEMP_STATS_DEC(err, MEMP_TCP_PCB);
01321     }
01322   }
01323   if (pcb != NULL) {
01324     memset(pcb, 0, sizeof(struct tcp_pcb));
01325     pcb->prio = prio;
01326     pcb->snd_buf = TCP_SND_BUF;
01327     pcb->snd_queuelen = 0;
01328     pcb->rcv_wnd = TCP_WND;
01329     pcb->rcv_ann_wnd = TCP_WND;
01330     pcb->tos = 0;
01331     pcb->ttl = TCP_TTL;
01332     /* As initial send MSS, we use TCP_MSS but limit it to 536.
01333        The send MSS is updated when an MSS option is received. */
01334     pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS;
01335     pcb->rto = 3000 / TCP_SLOW_INTERVAL;
01336     pcb->sa = 0;
01337     pcb->sv = 3000 / TCP_SLOW_INTERVAL;
01338     pcb->rtime = -1;
01339     pcb->cwnd = 1;
01340     iss = tcp_next_iss();
01341     pcb->snd_wl2 = iss;
01342     pcb->snd_nxt = iss;
01343     pcb->lastack = iss;
01344     pcb->snd_lbb = iss;
01345     pcb->tmr = tcp_ticks;
01346     pcb->last_timer = tcp_timer_ctr;
01347 
01348     pcb->polltmr = 0;
01349 
01350 #if LWIP_CALLBACK_API
01351     pcb->recv = tcp_recv_null;
01352 #endif /* LWIP_CALLBACK_API */
01353 
01354     /* Init KEEPALIVE timer */
01355     pcb->keep_idle  = TCP_KEEPIDLE_DEFAULT;
01356 
01357 #if LWIP_TCP_KEEPALIVE
01358     pcb->keep_intvl = TCP_KEEPINTVL_DEFAULT;
01359     pcb->keep_cnt   = TCP_KEEPCNT_DEFAULT;
01360 #endif /* LWIP_TCP_KEEPALIVE */
01361 
01362     pcb->keep_cnt_sent = 0;
01363   }
01364   return pcb;
01365 }
01366 
01367 /**
01368  * Creates a new TCP protocol control block but doesn't place it on
01369  * any of the TCP PCB lists.
01370  * The pcb is not put on any list until binding using tcp_bind().
01371  *
01372  * @internal: Maybe there should be a idle TCP PCB list where these
01373  * PCBs are put on. Port reservation using tcp_bind() is implemented but
01374  * allocated pcbs that are not bound can't be killed automatically if wanting
01375  * to allocate a pcb with higher prio (@see tcp_kill_prio())
01376  *
01377  * @return a new tcp_pcb that initially is in state CLOSED
01378  */
01379 struct tcp_pcb *
01380 tcp_new(void)
01381 {
01382   return tcp_alloc(TCP_PRIO_NORMAL);
01383 }
01384 
01385 /**
01386  * Used to specify the argument that should be passed callback
01387  * functions.
01388  *
01389  * @param pcb tcp_pcb to set the callback argument
01390  * @param arg void pointer argument to pass to callback functions
01391  */
01392 void
01393 tcp_arg(struct tcp_pcb *pcb, void *arg)
01394 {
01395   /* This function is allowed to be called for both listen pcbs and
01396      connection pcbs. */
01397   pcb->callback_arg = arg;
01398 }
01399 #if LWIP_CALLBACK_API
01400 
01401 /**
01402  * Used to specify the function that should be called when a TCP
01403  * connection receives data.
01404  *
01405  * @param pcb tcp_pcb to set the recv callback
01406  * @param recv callback function to call for this pcb when data is received
01407  */
01408 void
01409 tcp_recv(struct tcp_pcb *pcb, tcp_recv_fn recv)
01410 {
01411   LWIP_ASSERT("invalid socket state for recv callback", pcb->state != LISTEN);
01412   pcb->recv = recv;
01413 }
01414 
01415 /**
01416  * Used to specify the function that should be called when TCP data
01417  * has been successfully delivered to the remote host.
01418  *
01419  * @param pcb tcp_pcb to set the sent callback
01420  * @param sent callback function to call for this pcb when data is successfully sent
01421  */
01422 void
01423 tcp_sent(struct tcp_pcb *pcb, tcp_sent_fn sent)
01424 {
01425   LWIP_ASSERT("invalid socket state for sent callback", pcb->state != LISTEN);
01426   pcb->sent = sent;
01427 }
01428 
01429 /**
01430  * Used to specify the function that should be called when a fatal error
01431  * has occured on the connection.
01432  *
01433  * @param pcb tcp_pcb to set the err callback
01434  * @param err callback function to call for this pcb when a fatal error
01435  *        has occured on the connection
01436  */
01437 void
01438 tcp_err(struct tcp_pcb *pcb, tcp_err_fn err)
01439 {
01440   LWIP_ASSERT("invalid socket state for err callback", pcb->state != LISTEN);
01441   pcb->errf = err;
01442 }
01443 
01444 /**
01445  * Used for specifying the function that should be called when a
01446  * LISTENing connection has been connected to another host.
01447  *
01448  * @param pcb tcp_pcb to set the accept callback
01449  * @param accept callback function to call for this pcb when LISTENing
01450  *        connection has been connected to another host
01451  */
01452 void
01453 tcp_accept(struct tcp_pcb *pcb, tcp_accept_fn accept)
01454 {
01455   /* This function is allowed to be called for both listen pcbs and
01456      connection pcbs. */
01457   pcb->accept = accept;
01458 }
01459 #endif /* LWIP_CALLBACK_API */
01460 
01461 
01462 /**
01463  * Used to specify the function that should be called periodically
01464  * from TCP. The interval is specified in terms of the TCP coarse
01465  * timer interval, which is called twice a second.
01466  *
01467  */
01468 void
01469 tcp_poll(struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval)
01470 {
01471   LWIP_ASSERT("invalid socket state for poll", pcb->state != LISTEN);
01472 #if LWIP_CALLBACK_API
01473   pcb->poll = poll;
01474 #else /* LWIP_CALLBACK_API */
01475   LWIP_UNUSED_ARG(poll);
01476 #endif /* LWIP_CALLBACK_API */
01477   pcb->pollinterval = interval;
01478 }
01479 
01480 /**
01481  * Purges a TCP PCB. Removes any buffered data and frees the buffer memory
01482  * (pcb->ooseq, pcb->unsent and pcb->unacked are freed).
01483  *
01484  * @param pcb tcp_pcb to purge. The pcb itself is not deallocated!
01485  */
01486 void
01487 tcp_pcb_purge(struct tcp_pcb *pcb)
01488 {
01489   if (pcb->state != CLOSED &&
01490      pcb->state != TIME_WAIT &&
01491      pcb->state != LISTEN) {
01492 
01493     LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge\n"));
01494 
01495 #if TCP_LISTEN_BACKLOG
01496     if (pcb->state == SYN_RCVD) {
01497       /* Need to find the corresponding listen_pcb and decrease its accepts_pending */
01498       struct tcp_pcb_listen *lpcb;
01499       LWIP_ASSERT("tcp_pcb_purge: pcb->state == SYN_RCVD but tcp_listen_pcbs is NULL",
01500         tcp_listen_pcbs.listen_pcbs != NULL);
01501       for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
01502         if ((lpcb->local_port == pcb->local_port) &&
01503             (ip_addr_isany(&lpcb->local_ip) ||
01504              ip_addr_cmp(&pcb->local_ip, &lpcb->local_ip))) {
01505             /* port and address of the listen pcb match the timed-out pcb */
01506             LWIP_ASSERT("tcp_pcb_purge: listen pcb does not have accepts pending",
01507               lpcb->accepts_pending > 0);
01508             lpcb->accepts_pending--;
01509             break;
01510           }
01511       }
01512     }
01513 #endif /* TCP_LISTEN_BACKLOG */
01514 
01515 
01516     if (pcb->refused_data != NULL) {
01517       LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->refused_data\n"));
01518       pbuf_free(pcb->refused_data);
01519       pcb->refused_data = NULL;
01520     }
01521     if (pcb->unsent != NULL) {
01522       LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: not all data sent\n"));
01523     }
01524     if (pcb->unacked != NULL) {
01525       LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->unacked\n"));
01526     }
01527 #if TCP_QUEUE_OOSEQ
01528     if (pcb->ooseq != NULL) {
01529       LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n"));
01530     }
01531     tcp_segs_free(pcb->ooseq);
01532     pcb->ooseq = NULL;
01533 #endif /* TCP_QUEUE_OOSEQ */
01534 
01535     /* Stop the retransmission timer as it will expect data on unacked
01536        queue if it fires */
01537     pcb->rtime = -1;
01538 
01539     tcp_segs_free(pcb->unsent);
01540     tcp_segs_free(pcb->unacked);
01541     pcb->unacked = pcb->unsent = NULL;
01542 #if TCP_OVERSIZE
01543     pcb->unsent_oversize = 0;
01544 #endif /* TCP_OVERSIZE */
01545   }
01546 }
01547 
01548 /**
01549  * Purges the PCB and removes it from a PCB list. Any delayed ACKs are sent first.
01550  *
01551  * @param pcblist PCB list to purge.
01552  * @param pcb tcp_pcb to purge. The pcb itself is NOT deallocated!
01553  */
01554 void
01555 tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb)
01556 {
01557   TCP_RMV(pcblist, pcb);
01558 
01559   tcp_pcb_purge(pcb);
01560 
01561   /* if there is an outstanding delayed ACKs, send it */
01562   if (pcb->state != TIME_WAIT &&
01563      pcb->state != LISTEN &&
01564      pcb->flags & TF_ACK_DELAY) {
01565     pcb->flags |= TF_ACK_NOW;
01566     tcp_output(pcb);
01567   }
01568 
01569   if (pcb->state != LISTEN) {
01570     LWIP_ASSERT("unsent segments leaking", pcb->unsent == NULL);
01571     LWIP_ASSERT("unacked segments leaking", pcb->unacked == NULL);
01572 #if TCP_QUEUE_OOSEQ
01573     LWIP_ASSERT("ooseq segments leaking", pcb->ooseq == NULL);
01574 #endif /* TCP_QUEUE_OOSEQ */
01575   }
01576 
01577   pcb->state = CLOSED;
01578 
01579   LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane());
01580 }
01581 
01582 /**
01583  * Calculates a new initial sequence number for new connections.
01584  *
01585  * @return u32_t pseudo random sequence number
01586  */
01587 u32_t
01588 tcp_next_iss(void)
01589 {
01590   static u32_t iss = 6510;
01591 
01592   iss += tcp_ticks;       /* XXX */
01593   return iss;
01594 }
01595 
01596 #if TCP_CALCULATE_EFF_SEND_MSS
01597 /**
01598  * Calcluates the effective send mss that can be used for a specific IP address
01599  * by using ip_route to determin the netif used to send to the address and
01600  * calculating the minimum of TCP_MSS and that netif's mtu (if set).
01601  */
01602 u16_t
01603 tcp_eff_send_mss(u16_t sendmss, ip_addr_t *addr)
01604 {
01605   u16_t mss_s;
01606   struct netif *outif;
01607 
01608   outif = ip_route(addr);
01609   if ((outif != NULL) && (outif->mtu != 0)) {
01610     mss_s = outif->mtu - IP_HLEN - TCP_HLEN;
01611     /* RFC 1122, chap 4.2.2.6:
01612      * Eff.snd.MSS = min(SendMSS+20, MMS_S) - TCPhdrsize - IPoptionsize
01613      * We correct for TCP options in tcp_write(), and don't support IP options.
01614      */
01615     sendmss = LWIP_MIN(sendmss, mss_s);
01616   }
01617   return sendmss;
01618 }
01619 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
01620 
01621 const char*
01622 tcp_debug_state_str(enum tcp_state s)
01623 {
01624   return tcp_state_str[s];
01625 }
01626 
01627 #if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG
01628 /**
01629  * Print a tcp header for debugging purposes.
01630  *
01631  * @param tcphdr pointer to a struct tcp_hdr
01632  */
01633 void
01634 tcp_debug_print(struct tcp_hdr *tcphdr)
01635 {
01636   LWIP_DEBUGF(TCP_DEBUG, ("TCP header:\n"));
01637   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
01638   LWIP_DEBUGF(TCP_DEBUG, ("|    %5"U16_F"      |    %5"U16_F"      | (src port, dest port)\n",
01639          ntohs(tcphdr->src), ntohs(tcphdr->dest)));
01640   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
01641   LWIP_DEBUGF(TCP_DEBUG, ("|           %010"U32_F"          | (seq no)\n",
01642           ntohl(tcphdr->seqno)));
01643   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
01644   LWIP_DEBUGF(TCP_DEBUG, ("|           %010"U32_F"          | (ack no)\n",
01645          ntohl(tcphdr->ackno)));
01646   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
01647   LWIP_DEBUGF(TCP_DEBUG, ("| %2"U16_F" |   |%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"|     %5"U16_F"     | (hdrlen, flags (",
01648        TCPH_HDRLEN(tcphdr),
01649          TCPH_FLAGS(tcphdr) >> 5 & 1,
01650          TCPH_FLAGS(tcphdr) >> 4 & 1,
01651          TCPH_FLAGS(tcphdr) >> 3 & 1,
01652          TCPH_FLAGS(tcphdr) >> 2 & 1,
01653          TCPH_FLAGS(tcphdr) >> 1 & 1,
01654          TCPH_FLAGS(tcphdr) & 1,
01655          ntohs(tcphdr->wnd)));
01656   tcp_debug_print_flags(TCPH_FLAGS(tcphdr));
01657   LWIP_DEBUGF(TCP_DEBUG, ("), win)\n"));
01658   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
01659   LWIP_DEBUGF(TCP_DEBUG, ("|    0x%04"X16_F"     |     %5"U16_F"     | (chksum, urgp)\n",
01660          ntohs(tcphdr->chksum), ntohs(tcphdr->urgp)));
01661   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
01662 }
01663 
01664 /**
01665  * Print a tcp state for debugging purposes.
01666  *
01667  * @param s enum tcp_state to print
01668  */
01669 void
01670 tcp_debug_print_state(enum tcp_state s)
01671 {
01672   LWIP_DEBUGF(TCP_DEBUG, ("State: %s\n", tcp_state_str[s]));
01673 }
01674 
01675 /**
01676  * Print tcp flags for debugging purposes.
01677  *
01678  * @param flags tcp flags, all active flags are printed
01679  */
01680 void
01681 tcp_debug_print_flags(u8_t flags)
01682 {
01683   if (flags & TCP_FIN) {
01684     LWIP_DEBUGF(TCP_DEBUG, ("FIN "));
01685   }
01686   if (flags & TCP_SYN) {
01687     LWIP_DEBUGF(TCP_DEBUG, ("SYN "));
01688   }
01689   if (flags & TCP_RST) {
01690     LWIP_DEBUGF(TCP_DEBUG, ("RST "));
01691   }
01692   if (flags & TCP_PSH) {
01693     LWIP_DEBUGF(TCP_DEBUG, ("PSH "));
01694   }
01695   if (flags & TCP_ACK) {
01696     LWIP_DEBUGF(TCP_DEBUG, ("ACK "));
01697   }
01698   if (flags & TCP_URG) {
01699     LWIP_DEBUGF(TCP_DEBUG, ("URG "));
01700   }
01701   if (flags & TCP_ECE) {
01702     LWIP_DEBUGF(TCP_DEBUG, ("ECE "));
01703   }
01704   if (flags & TCP_CWR) {
01705     LWIP_DEBUGF(TCP_DEBUG, ("CWR "));
01706   }
01707   LWIP_DEBUGF(TCP_DEBUG, ("\n"));
01708 }
01709 
01710 /**
01711  * Print all tcp_pcbs in every list for debugging purposes.
01712  */
01713 void
01714 tcp_debug_print_pcbs(void)
01715 {
01716   struct tcp_pcb *pcb;
01717   LWIP_DEBUGF(TCP_DEBUG, ("Active PCB states:\n"));
01718   for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
01719     LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
01720                        pcb->local_port, pcb->remote_port,
01721                        pcb->snd_nxt, pcb->rcv_nxt));
01722     tcp_debug_print_state(pcb->state);
01723   }
01724   LWIP_DEBUGF(TCP_DEBUG, ("Listen PCB states:\n"));
01725   for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) {
01726     LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
01727                        pcb->local_port, pcb->remote_port,
01728                        pcb->snd_nxt, pcb->rcv_nxt));
01729     tcp_debug_print_state(pcb->state);
01730   }
01731   LWIP_DEBUGF(TCP_DEBUG, ("TIME-WAIT PCB states:\n"));
01732   for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
01733     LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
01734                        pcb->local_port, pcb->remote_port,
01735                        pcb->snd_nxt, pcb->rcv_nxt));
01736     tcp_debug_print_state(pcb->state);
01737   }
01738 }
01739 
01740 /**
01741  * Check state consistency of the tcp_pcb lists.
01742  */
01743 s16_t
01744 tcp_pcbs_sane(void)
01745 {
01746   struct tcp_pcb *pcb;
01747   for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
01748     LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != CLOSED", pcb->state != CLOSED);
01749     LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != LISTEN", pcb->state != LISTEN);
01750     LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
01751   }
01752   for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
01753     LWIP_ASSERT("tcp_pcbs_sane: tw pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
01754   }
01755   return 1;
01756 }
01757 #endif /* TCP_DEBUG */
01758 
01759 #endif /* LWIP_TCP */