Web server based weather station using Sparkfun Weather Meters.

Dependencies:   FatFileSystem mbed WeatherMeters SDFileSystem

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