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