ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

tcp.c
Go to the documentation of this file.
00001 
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 
00082 struct tcp_pcb *tcp_bound_pcbs;
00084 union tcp_listen_pcbs_t tcp_listen_pcbs;
00087 struct tcp_pcb *tcp_active_pcbs;
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 
00094 struct tcp_pcb ** const tcp_pcb_lists[] = {&tcp_listen_pcbs.pcbs, &tcp_bound_pcbs,
00095   &tcp_active_pcbs, &tcp_tw_pcbs};
00096 
00098 struct tcp_pcb *tcp_tmp_pcb;
00099 
00101 static u8_t tcp_timer;
00102 static u16_t tcp_new_port(void);
00103 
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 
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     if (pcb->local_port != 0) {
00177       TCP_RMV(&tcp_bound_pcbs, pcb);
00178     }
00179     memp_free(MEMP_TCP_PCB, pcb);
00180     pcb = NULL;
00181     break;
00182   case LISTEN:
00183     err = ERR_OK;
00184     tcp_pcb_remove(&tcp_listen_pcbs.pcbs, pcb);
00185     memp_free(MEMP_TCP_PCB_LISTEN, pcb);
00186     pcb = NULL;
00187     break;
00188   case SYN_SENT:
00189     err = ERR_OK;
00190     tcp_pcb_remove(&tcp_active_pcbs, pcb);
00191     memp_free(MEMP_TCP_PCB, pcb);
00192     pcb = NULL;
00193     snmp_inc_tcpattemptfails();
00194     break;
00195   case SYN_RCVD:
00196     err = tcp_send_fin(pcb);
00197     if (err == ERR_OK) {
00198       snmp_inc_tcpattemptfails();
00199       pcb->state = FIN_WAIT_1;
00200     }
00201     break;
00202   case ESTABLISHED:
00203     err = tcp_send_fin(pcb);
00204     if (err == ERR_OK) {
00205       snmp_inc_tcpestabresets();
00206       pcb->state = FIN_WAIT_1;
00207     }
00208     break;
00209   case CLOSE_WAIT:
00210     err = tcp_send_fin(pcb);
00211     if (err == ERR_OK) {
00212       snmp_inc_tcpestabresets();
00213       pcb->state = LAST_ACK;
00214     }
00215     break;
00216   default:
00217     /* Has already been closed, do nothing. */
00218     err = ERR_OK;
00219     pcb = NULL;
00220     break;
00221   }
00222 
00223   if (pcb != NULL && err == ERR_OK) {
00224     /* To ensure all data has been sent when tcp_close returns, we have
00225        to make sure tcp_output doesn't fail.
00226        Since we don't really have to ensure all data has been sent when tcp_close
00227        returns (unsent data is sent from tcp timer functions, also), we don't care
00228        for the return value of tcp_output for now. */
00229     /* @todo: When implementing SO_LINGER, this must be changed somehow:
00230        If SOF_LINGER is set, the data should be sent and acked before close returns.
00231        This can only be valid for sequential APIs, not for the raw API. */
00232     tcp_output(pcb);
00233   }
00234   return err;
00235 }
00236 
00251 err_t
00252 tcp_close(struct tcp_pcb *pcb)
00253 {
00254 #if TCP_DEBUG
00255   LWIP_DEBUGF(TCP_DEBUG, ("tcp_close: closing in "));
00256   tcp_debug_print_state(pcb->state);
00257 #endif /* TCP_DEBUG */
00258 
00259   if (pcb->state != LISTEN) {
00260     /* Set a flag not to receive any more data... */
00261     pcb->flags |= TF_RXCLOSED;
00262   }
00263   /* ... and close */
00264   return tcp_close_shutdown(pcb, 1);
00265 }
00266 
00277 err_t
00278 tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx)
00279 {
00280   if (pcb->state == LISTEN) {
00281     return ERR_CONN;
00282   }
00283   if (shut_rx) {
00284     /* shut down the receive side: free buffered data... */
00285     if (pcb->refused_data != NULL) {
00286       pbuf_free(pcb->refused_data);
00287       pcb->refused_data = NULL;
00288     }
00289     /* ... and set a flag not to receive any more data */
00290     pcb->flags |= TF_RXCLOSED;
00291   }
00292   if (shut_tx) {
00293     /* This can't happen twice since if it succeeds, the pcb's state is changed.
00294        Only close in these states as the others directly deallocate the PCB */
00295     switch (pcb->state) {
00296   case SYN_RCVD:
00297   case ESTABLISHED:
00298   case CLOSE_WAIT:
00299     return tcp_close_shutdown(pcb, 0);
00300   default:
00301     /* don't shut down other states */
00302     break;
00303     }
00304   }
00305   /* @todo: return another err_t if not in correct state or already shut? */
00306   return ERR_OK;
00307 }
00308 
00317 void
00318 tcp_abandon(struct tcp_pcb *pcb, int reset)
00319 {
00320   u32_t seqno, ackno;
00321   u16_t remote_port, local_port;
00322   ip_addr_t remote_ip, local_ip;
00323 #if LWIP_CALLBACK_API  
00324   tcp_err_fn errf;
00325 #endif /* LWIP_CALLBACK_API */
00326   void *errf_arg;
00327 
00328   /* pcb->state LISTEN not allowed here */
00329   LWIP_ASSERT("don't call tcp_abort/tcp_abandon for listen-pcbs",
00330     pcb->state != LISTEN);
00331   /* Figure out on which TCP PCB list we are, and remove us. If we
00332      are in an active state, call the receive function associated with
00333      the PCB with a NULL argument, and send an RST to the remote end. */
00334   if (pcb->state == TIME_WAIT) {
00335     tcp_pcb_remove(&tcp_tw_pcbs, pcb);
00336     memp_free(MEMP_TCP_PCB, pcb);
00337   } else {
00338     seqno = pcb->snd_nxt;
00339     ackno = pcb->rcv_nxt;
00340     ip_addr_copy(local_ip, pcb->local_ip);
00341     ip_addr_copy(remote_ip, pcb->remote_ip);
00342     local_port = pcb->local_port;
00343     remote_port = pcb->remote_port;
00344 #if LWIP_CALLBACK_API
00345     errf = pcb->errf;
00346 #endif /* LWIP_CALLBACK_API */
00347     errf_arg = pcb->callback_arg;
00348     tcp_pcb_remove(&tcp_active_pcbs, pcb);
00349     if (pcb->unacked != NULL) {
00350       tcp_segs_free(pcb->unacked);
00351     }
00352     if (pcb->unsent != NULL) {
00353       tcp_segs_free(pcb->unsent);
00354     }
00355 #if TCP_QUEUE_OOSEQ    
00356     if (pcb->ooseq != NULL) {
00357       tcp_segs_free(pcb->ooseq);
00358     }
00359 #endif /* TCP_QUEUE_OOSEQ */
00360     memp_free(MEMP_TCP_PCB, pcb);
00361     TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT);
00362     if (reset) {
00363       LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abandon: sending RST\n"));
00364       tcp_rst(seqno, ackno, &local_ip, &remote_ip, local_port, remote_port);
00365     }
00366   }
00367 }
00368 
00379 void
00380 tcp_abort(struct tcp_pcb *pcb)
00381 {
00382   tcp_abandon(pcb, 1);
00383 }
00384 
00399 err_t
00400 tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port)
00401 {
00402   int i;
00403   int max_pcb_list = NUM_TCP_PCB_LISTS;
00404   struct tcp_pcb *cpcb;
00405 
00406   LWIP_ERROR("tcp_bind: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_VAL);
00407 
00408 #if SO_REUSE
00409   /* Unless the REUSEADDR flag is set,
00410      we have to check the pcbs in TIME-WAIT state, also.
00411      We do not dump TIME_WAIT pcb's; they can still be matched by incoming
00412      packets using both local and remote IP addresses and ports to distinguish.
00413    */
00414   if ((pcb->so_options & SOF_REUSEADDR) != 0) {
00415     max_pcb_list = NUM_TCP_PCB_LISTS_NO_TIME_WAIT;
00416   }
00417 #endif /* SO_REUSE */
00418 
00419   if (port == 0) {
00420     port = tcp_new_port();
00421   }
00422 
00423   /* Check if the address already is in use (on all lists) */
00424   for (i = 0; i < max_pcb_list; i++) {
00425     for(cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) {
00426       if (cpcb->local_port == port) {
00427 #if SO_REUSE
00428         /* Omit checking for the same port if both pcbs have REUSEADDR set.
00429            For SO_REUSEADDR, the duplicate-check for a 5-tuple is done in
00430            tcp_connect. */
00431         if (((pcb->so_options & SOF_REUSEADDR) == 0) ||
00432           ((cpcb->so_options & SOF_REUSEADDR) == 0))
00433 #endif /* SO_REUSE */
00434         {
00435           if (ip_addr_isany(&(cpcb->local_ip)) ||
00436               ip_addr_isany(ipaddr) ||
00437               ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {
00438             return ERR_USE;
00439           }
00440         }
00441       }
00442     }
00443   }
00444 
00445   if (!ip_addr_isany(ipaddr)) {
00446     pcb->local_ip = *ipaddr;
00447   }
00448   pcb->local_port = port;
00449   TCP_REG(&tcp_bound_pcbs, pcb);
00450   LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %"U16_F"\n", port));
00451   return ERR_OK;
00452 }
00453 #if LWIP_CALLBACK_API
00454 
00457 static err_t
00458 tcp_accept_null(void *arg, struct tcp_pcb *pcb, err_t err)
00459 {
00460   LWIP_UNUSED_ARG(arg);
00461   LWIP_UNUSED_ARG(pcb);
00462   LWIP_UNUSED_ARG(err);
00463 
00464   return ERR_ABRT;
00465 }
00466 #endif /* LWIP_CALLBACK_API */
00467 
00482 struct tcp_pcb *
00483 tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
00484 {
00485   struct tcp_pcb_listen *lpcb;
00486 
00487   LWIP_UNUSED_ARG(backlog);
00488   LWIP_ERROR("tcp_listen: pcb already connected", pcb->state == CLOSED, return NULL);
00489 
00490   /* already listening? */
00491   if (pcb->state == LISTEN) {
00492     return pcb;
00493   }
00494 #if SO_REUSE
00495   if ((pcb->so_options & SOF_REUSEADDR) != 0) {
00496     /* Since SOF_REUSEADDR allows reusing a local address before the pcb's usage
00497        is declared (listen-/connection-pcb), we have to make sure now that
00498        this port is only used once for every local IP. */
00499     for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
00500       if (lpcb->local_port == pcb->local_port) {
00501         if (ip_addr_cmp(&lpcb->local_ip, &pcb->local_ip)) {
00502           /* this address/port is already used */
00503           return NULL;
00504         }
00505       }
00506     }
00507   }
00508 #endif /* SO_REUSE */
00509   lpcb = (struct tcp_pcb_listen *)memp_malloc(MEMP_TCP_PCB_LISTEN);
00510   if (lpcb == NULL) {
00511     return NULL;
00512   }
00513   lpcb->callback_arg = pcb->callback_arg;
00514   lpcb->local_port = pcb->local_port;
00515   lpcb->state = LISTEN;
00516   lpcb->prio = pcb->prio;
00517   lpcb->so_options = pcb->so_options;
00518   lpcb->so_options |= SOF_ACCEPTCONN;
00519   lpcb->ttl = pcb->ttl;
00520   lpcb->tos = pcb->tos;
00521   ip_addr_copy(lpcb->local_ip, pcb->local_ip);
00522   if (pcb->local_port != 0) {
00523     TCP_RMV(&tcp_bound_pcbs, pcb);
00524   }
00525   memp_free(MEMP_TCP_PCB, pcb);
00526 #if LWIP_CALLBACK_API
00527   lpcb->accept = tcp_accept_null;
00528 #endif /* LWIP_CALLBACK_API */
00529 #if TCP_LISTEN_BACKLOG
00530   lpcb->accepts_pending = 0;
00531   lpcb->backlog = (backlog ? backlog : 1);
00532 #endif /* TCP_LISTEN_BACKLOG */
00533   TCP_REG(&tcp_listen_pcbs.pcbs, (struct tcp_pcb *)lpcb);
00534   return (struct tcp_pcb *)lpcb;
00535 }
00536 
00543 u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb)
00544 {
00545   u32_t new_right_edge = pcb->rcv_nxt + pcb->rcv_wnd;
00546 
00547   if (TCP_SEQ_GEQ(new_right_edge, pcb->rcv_ann_right_edge + LWIP_MIN((TCP_WND / 2), pcb->mss))) {
00548     /* we can advertise more window */
00549     pcb->rcv_ann_wnd = pcb->rcv_wnd;
00550     return new_right_edge - pcb->rcv_ann_right_edge;
00551   } else {
00552     if (TCP_SEQ_GT(pcb->rcv_nxt, pcb->rcv_ann_right_edge)) {
00553       /* Can happen due to other end sending out of advertised window,
00554        * but within actual available (but not yet advertised) window */
00555       pcb->rcv_ann_wnd = 0;
00556     } else {
00557       /* keep the right edge of window constant */
00558       u32_t new_rcv_ann_wnd = pcb->rcv_ann_right_edge - pcb->rcv_nxt;
00559       LWIP_ASSERT("new_rcv_ann_wnd <= 0xffff", new_rcv_ann_wnd <= 0xffff);
00560       pcb->rcv_ann_wnd = (u16_t)new_rcv_ann_wnd;
00561     }
00562     return 0;
00563   }
00564 }
00565 
00574 void
00575 tcp_recved(struct tcp_pcb *pcb, u16_t len)
00576 {
00577   int wnd_inflation;
00578 
00579   LWIP_ASSERT("tcp_recved: len would wrap rcv_wnd\n",
00580               len <= 0xffff - pcb->rcv_wnd );
00581 
00582   pcb->rcv_wnd += len;
00583   if (pcb->rcv_wnd > TCP_WND) {
00584     pcb->rcv_wnd = TCP_WND;
00585   }
00586 
00587   wnd_inflation = tcp_update_rcv_ann_wnd(pcb);
00588 
00589   /* If the change in the right edge of window is significant (default
00590    * watermark is TCP_WND/4), then send an explicit update now.
00591    * Otherwise wait for a packet to be sent in the normal course of
00592    * events (or more window to be available later) */
00593   if (wnd_inflation >= TCP_WND_UPDATE_THRESHOLD) {
00594     tcp_ack_now(pcb);
00595     tcp_output(pcb);
00596   }
00597 
00598   LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: recveived %"U16_F" bytes, wnd %"U16_F" (%"U16_F").\n",
00599          len, pcb->rcv_wnd, TCP_WND - pcb->rcv_wnd));
00600 }
00601 
00608 static u16_t
00609 tcp_new_port(void)
00610 {
00611   int i;
00612   struct tcp_pcb *pcb;
00613 #ifndef TCP_LOCAL_PORT_RANGE_START
00614 /* From http://www.iana.org/assignments/port-numbers:
00615    "The Dynamic and/or Private Ports are those from 49152 through 65535" */
00616 #define TCP_LOCAL_PORT_RANGE_START  0xc000
00617 #define TCP_LOCAL_PORT_RANGE_END    0xffff
00618 #endif
00619   static u16_t port = TCP_LOCAL_PORT_RANGE_START;
00620   
00621  again:
00622   if (port++ >= TCP_LOCAL_PORT_RANGE_END) {
00623     port = TCP_LOCAL_PORT_RANGE_START;
00624   }
00625   /* Check all PCB lists. */
00626   for (i = 0; i < NUM_TCP_PCB_LISTS; i++) {
00627     for(pcb = *tcp_pcb_lists[i]; pcb != NULL; pcb = pcb->next) {
00628       if (pcb->local_port == port) {
00629         goto again;
00630       }
00631     }
00632   }
00633   return port;
00634 }
00635 
00648 err_t
00649 tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port,
00650       tcp_connected_fn connected)
00651 {
00652   err_t ret;
00653   u32_t iss;
00654   u16_t old_local_port;
00655 
00656   LWIP_ERROR("tcp_connect: can only connect from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN);
00657 
00658   LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port));
00659   if (ipaddr != NULL) {
00660     pcb->remote_ip = *ipaddr;
00661   } else {
00662     return ERR_VAL;
00663   }
00664   pcb->remote_port = port;
00665 
00666   /* check if we have a route to the remote host */
00667   if (ip_addr_isany(&(pcb->local_ip))) {
00668     /* no local IP address set, yet. */
00669     struct netif *netif = ip_route(&(pcb->remote_ip));
00670     if (netif == NULL) {
00671       /* Don't even try to send a SYN packet if we have no route
00672          since that will fail. */
00673       return ERR_RTE;
00674     }
00675     /* Use the netif's IP address as local address. */
00676     ip_addr_copy(pcb->local_ip, netif->ip_addr);
00677   }
00678 
00679   old_local_port = pcb->local_port;
00680   if (pcb->local_port == 0) {
00681     pcb->local_port = tcp_new_port();
00682   }
00683 #if SO_REUSE
00684   if ((pcb->so_options & SOF_REUSEADDR) != 0) {
00685     /* Since SOF_REUSEADDR allows reusing a local address, we have to make sure
00686        now that the 5-tuple is unique. */
00687     struct tcp_pcb *cpcb;
00688     int i;
00689     /* Don't check listen- and bound-PCBs, check active- and TIME-WAIT PCBs. */
00690     for (i = 2; i < NUM_TCP_PCB_LISTS; i++) {
00691       for(cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) {
00692         if ((cpcb->local_port == pcb->local_port) &&
00693             (cpcb->remote_port == port) &&
00694             ip_addr_cmp(&cpcb->local_ip, &pcb->local_ip) &&
00695             ip_addr_cmp(&cpcb->remote_ip, ipaddr)) {
00696           /* linux returns EISCONN here, but ERR_USE should be OK for us */
00697           return ERR_USE;
00698         }
00699       }
00700     }
00701   }
00702 #endif /* SO_REUSE */
00703   iss = tcp_next_iss();
00704   pcb->rcv_nxt = 0;
00705   pcb->snd_nxt = iss;
00706   pcb->lastack = iss - 1;
00707   pcb->snd_lbb = iss - 1;
00708   pcb->rcv_wnd = TCP_WND;
00709   pcb->rcv_ann_wnd = TCP_WND;
00710   pcb->rcv_ann_right_edge = pcb->rcv_nxt;
00711   pcb->snd_wnd = TCP_WND;
00712   /* As initial send MSS, we use TCP_MSS but limit it to 536.
00713      The send MSS is updated when an MSS option is received. */
00714   pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS;
00715 #if TCP_CALCULATE_EFF_SEND_MSS
00716   pcb->mss = tcp_eff_send_mss(pcb->mss, ipaddr);
00717 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
00718   pcb->cwnd = 1;
00719   pcb->ssthresh = pcb->mss * 10;
00720 #if LWIP_CALLBACK_API
00721   pcb->connected = connected;
00722 #else /* LWIP_CALLBACK_API */  
00723   LWIP_UNUSED_ARG(connected);
00724 #endif /* LWIP_CALLBACK_API */
00725 
00726   /* Send a SYN together with the MSS option. */
00727   ret = tcp_enqueue_flags(pcb, TCP_SYN);
00728   if (ret == ERR_OK) {
00729     /* SYN segment was enqueued, changed the pcbs state now */
00730     pcb->state = SYN_SENT;
00731     if (old_local_port != 0) {
00732       TCP_RMV(&tcp_bound_pcbs, pcb);
00733     }
00734     TCP_REG(&tcp_active_pcbs, pcb);
00735     snmp_inc_tcpactiveopens();
00736 
00737     tcp_output(pcb);
00738   }
00739   return ret;
00740 }
00741 
00749 void
00750 tcp_slowtmr(void)
00751 {
00752   struct tcp_pcb *pcb, *prev;
00753   u16_t eff_wnd;
00754   u8_t pcb_remove;      /* flag if a PCB should be removed */
00755   u8_t pcb_reset;       /* flag if a RST should be sent when removing */
00756   err_t err;
00757 
00758   err = ERR_OK;
00759 
00760   ++tcp_ticks;
00761 
00762   /* Steps through all of the active PCBs. */
00763   prev = NULL;
00764   pcb = tcp_active_pcbs;
00765   if (pcb == NULL) {
00766     LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n"));
00767   }
00768   while (pcb != NULL) {
00769     LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb\n"));
00770     LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED);
00771     LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN);
00772     LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT);
00773 
00774     pcb_remove = 0;
00775     pcb_reset = 0;
00776 
00777     if (pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) {
00778       ++pcb_remove;
00779       LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n"));
00780     }
00781     else if (pcb->nrtx == TCP_MAXRTX) {
00782       ++pcb_remove;
00783       LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n"));
00784     } else {
00785       if (pcb->persist_backoff > 0) {
00786         /* If snd_wnd is zero, use persist timer to send 1 byte probes
00787          * instead of using the standard retransmission mechanism. */
00788         pcb->persist_cnt++;
00789         if (pcb->persist_cnt >= tcp_persist_backoff[pcb->persist_backoff-1]) {
00790           pcb->persist_cnt = 0;
00791           if (pcb->persist_backoff < sizeof(tcp_persist_backoff)) {
00792             pcb->persist_backoff++;
00793           }
00794           tcp_zero_window_probe(pcb);
00795         }
00796       } else {
00797         /* Increase the retransmission timer if it is running */
00798         if(pcb->rtime >= 0)
00799           ++pcb->rtime;
00800 
00801         if (pcb->unacked != NULL && pcb->rtime >= pcb->rto) {
00802           /* Time for a retransmission. */
00803           LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %"S16_F
00804                                       " pcb->rto %"S16_F"\n",
00805                                       pcb->rtime, pcb->rto));
00806 
00807           /* Double retransmission time-out unless we are trying to
00808            * connect to somebody (i.e., we are in SYN_SENT). */
00809           if (pcb->state != SYN_SENT) {
00810             pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx];
00811           }
00812 
00813           /* Reset the retransmission timer. */
00814           pcb->rtime = 0;
00815 
00816           /* Reduce congestion window and ssthresh. */
00817           eff_wnd = LWIP_MIN(pcb->cwnd, pcb->snd_wnd);
00818           pcb->ssthresh = eff_wnd >> 1;
00819           if (pcb->ssthresh < (pcb->mss << 1)) {
00820             pcb->ssthresh = (pcb->mss << 1);
00821           }
00822           pcb->cwnd = pcb->mss;
00823           LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: cwnd %"U16_F
00824                                        " ssthresh %"U16_F"\n",
00825                                        pcb->cwnd, pcb->ssthresh));
00826  
00827           /* The following needs to be called AFTER cwnd is set to one
00828              mss - STJ */
00829           tcp_rexmit_rto(pcb);
00830         }
00831       }
00832     }
00833     /* Check if this PCB has stayed too long in FIN-WAIT-2 */
00834     if (pcb->state == FIN_WAIT_2) {
00835       if ((u32_t)(tcp_ticks - pcb->tmr) >
00836           TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) {
00837         ++pcb_remove;
00838         LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n"));
00839       }
00840     }
00841 
00842     /* Check if KEEPALIVE should be sent */
00843     if((pcb->so_options & SOF_KEEPALIVE) &&
00844        ((pcb->state == ESTABLISHED) ||
00845         (pcb->state == CLOSE_WAIT))) {
00846 #if LWIP_TCP_KEEPALIVE
00847       if((u32_t)(tcp_ticks - pcb->tmr) >
00848          (pcb->keep_idle + (pcb->keep_cnt*pcb->keep_intvl))
00849          / TCP_SLOW_INTERVAL)
00850 #else      
00851       if((u32_t)(tcp_ticks - pcb->tmr) >
00852          (pcb->keep_idle + TCP_MAXIDLE) / TCP_SLOW_INTERVAL)
00853 #endif /* LWIP_TCP_KEEPALIVE */
00854       {
00855         LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to %"U16_F".%"U16_F".%"U16_F".%"U16_F".\n",
00856                                 ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip),
00857                                 ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip)));
00858         
00859         ++pcb_remove;
00860         ++pcb_reset;
00861       }
00862 #if LWIP_TCP_KEEPALIVE
00863       else if((u32_t)(tcp_ticks - pcb->tmr) > 
00864               (pcb->keep_idle + pcb->keep_cnt_sent * pcb->keep_intvl)
00865               / TCP_SLOW_INTERVAL)
00866 #else
00867       else if((u32_t)(tcp_ticks - pcb->tmr) > 
00868               (pcb->keep_idle + pcb->keep_cnt_sent * TCP_KEEPINTVL_DEFAULT) 
00869               / TCP_SLOW_INTERVAL)
00870 #endif /* LWIP_TCP_KEEPALIVE */
00871       {
00872         tcp_keepalive(pcb);
00873         pcb->keep_cnt_sent++;
00874       }
00875     }
00876 
00877     /* If this PCB has queued out of sequence data, but has been
00878        inactive for too long, will drop the data (it will eventually
00879        be retransmitted). */
00880 #if TCP_QUEUE_OOSEQ
00881     if (pcb->ooseq != NULL &&
00882         (u32_t)tcp_ticks - pcb->tmr >= pcb->rto * TCP_OOSEQ_TIMEOUT) {
00883       tcp_segs_free(pcb->ooseq);
00884       pcb->ooseq = NULL;
00885       LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: dropping OOSEQ queued data\n"));
00886     }
00887 #endif /* TCP_QUEUE_OOSEQ */
00888 
00889     /* Check if this PCB has stayed too long in SYN-RCVD */
00890     if (pcb->state == SYN_RCVD) {
00891       if ((u32_t)(tcp_ticks - pcb->tmr) >
00892           TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) {
00893         ++pcb_remove;
00894         LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n"));
00895       }
00896     }
00897 
00898     /* Check if this PCB has stayed too long in LAST-ACK */
00899     if (pcb->state == LAST_ACK) {
00900       if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {
00901         ++pcb_remove;
00902         LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in LAST-ACK\n"));
00903       }
00904     }
00905 
00906     /* If the PCB should be removed, do it. */
00907     if (pcb_remove) {
00908       struct tcp_pcb *pcb2;
00909       tcp_pcb_purge(pcb);
00910       /* Remove PCB from tcp_active_pcbs list. */
00911       if (prev != NULL) {
00912         LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs);
00913         prev->next = pcb->next;
00914       } else {
00915         /* This PCB was the first. */
00916         LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb);
00917         tcp_active_pcbs = pcb->next;
00918       }
00919 
00920       TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_ABRT);
00921       if (pcb_reset) {
00922         tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip,
00923           pcb->local_port, pcb->remote_port);
00924       }
00925 
00926       pcb2 = pcb;
00927       pcb = pcb->next;
00928       memp_free(MEMP_TCP_PCB, pcb2);
00929     } else {
00930       /* get the 'next' element now and work with 'prev' below (in case of abort) */
00931       prev = pcb;
00932       pcb = pcb->next;
00933 
00934       /* We check if we should poll the connection. */
00935       ++prev->polltmr;
00936       if (prev->polltmr >= prev->pollinterval) {
00937         prev->polltmr = 0;
00938         LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n"));
00939         TCP_EVENT_POLL(prev, err);
00940         /* if err == ERR_ABRT, 'prev' is already deallocated */
00941         if (err == ERR_OK) {
00942           tcp_output(prev);
00943         }
00944       }
00945     }
00946   }
00947 
00948   
00949   /* Steps through all of the TIME-WAIT PCBs. */
00950   prev = NULL;
00951   pcb = tcp_tw_pcbs;
00952   while (pcb != NULL) {
00953     LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
00954     pcb_remove = 0;
00955 
00956     /* Check if this PCB has stayed long enough in TIME-WAIT */
00957     if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {
00958       ++pcb_remove;
00959     }
00960     
00961 
00962 
00963     /* If the PCB should be removed, do it. */
00964     if (pcb_remove) {
00965       struct tcp_pcb *pcb2;
00966       tcp_pcb_purge(pcb);
00967       /* Remove PCB from tcp_tw_pcbs list. */
00968       if (prev != NULL) {
00969         LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs);
00970         prev->next = pcb->next;
00971       } else {
00972         /* This PCB was the first. */
00973         LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb);
00974         tcp_tw_pcbs = pcb->next;
00975       }
00976       pcb2 = pcb;
00977       pcb = pcb->next;
00978       memp_free(MEMP_TCP_PCB, pcb2);
00979     } else {
00980       prev = pcb;
00981       pcb = pcb->next;
00982     }
00983   }
00984 }
00985 
00992 void
00993 tcp_fasttmr(void)
00994 {
00995   struct tcp_pcb *pcb = tcp_active_pcbs;
00996 
00997   while(pcb != NULL) {
00998     struct tcp_pcb *next = pcb->next;
00999     /* If there is data which was previously "refused" by upper layer */
01000     if (pcb->refused_data != NULL) {
01001       /* Notify again application with data previously received. */
01002       err_t err;
01003       LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_fasttmr: notify kept packet\n"));
01004       TCP_EVENT_RECV(pcb, pcb->refused_data, ERR_OK, err);
01005       if (err == ERR_OK) {
01006         pcb->refused_data = NULL;
01007       } else if (err == ERR_ABRT) {
01008         /* if err == ERR_ABRT, 'pcb' is already deallocated */
01009         pcb = NULL;
01010       }
01011     }
01012 
01013     /* send delayed ACKs */
01014     if (pcb && (pcb->flags & TF_ACK_DELAY)) {
01015       LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n"));
01016       tcp_ack_now(pcb);
01017       tcp_output(pcb);
01018       pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
01019     }
01020 
01021     pcb = next;
01022   }
01023 }
01024 
01030 void
01031 tcp_segs_free(struct tcp_seg *seg)
01032 {
01033   while (seg != NULL) {
01034     struct tcp_seg *next = seg->next;
01035     tcp_seg_free(seg);
01036     seg = next;
01037   }
01038 }
01039 
01045 void
01046 tcp_seg_free(struct tcp_seg *seg)
01047 {
01048   if (seg != NULL) {
01049     if (seg->p != NULL) {
01050       pbuf_free(seg->p);
01051 #if TCP_DEBUG
01052       seg->p = NULL;
01053 #endif /* TCP_DEBUG */
01054     }
01055     memp_free(MEMP_TCP_SEG, seg);
01056   }
01057 }
01058 
01065 void
01066 tcp_setprio(struct tcp_pcb *pcb, u8_t prio)
01067 {
01068   pcb->prio = prio;
01069 }
01070 
01071 #if TCP_QUEUE_OOSEQ
01072 
01079 struct tcp_seg *
01080 tcp_seg_copy(struct tcp_seg *seg)
01081 {
01082   struct tcp_seg *cseg;
01083 
01084   cseg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG);
01085   if (cseg == NULL) {
01086     return NULL;
01087   }
01088   SMEMCPY((u8_t *)cseg, (const u8_t *)seg, sizeof(struct tcp_seg)); 
01089   pbuf_ref(cseg->p);
01090   return cseg;
01091 }
01092 #endif /* TCP_QUEUE_OOSEQ */
01093 
01094 #if LWIP_CALLBACK_API
01095 
01099 err_t
01100 tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
01101 {
01102   LWIP_UNUSED_ARG(arg);
01103   if (p != NULL) {
01104     tcp_recved(pcb, p->tot_len);
01105     pbuf_free(p);
01106   } else if (err == ERR_OK) {
01107     return tcp_close(pcb);
01108   }
01109   return ERR_OK;
01110 }
01111 #endif /* LWIP_CALLBACK_API */
01112 
01118 static void
01119 tcp_kill_prio(u8_t prio)
01120 {
01121   struct tcp_pcb *pcb, *inactive;
01122   u32_t inactivity;
01123   u8_t mprio;
01124 
01125 
01126   mprio = TCP_PRIO_MAX;
01127   
01128   /* We kill the oldest active connection that has lower priority than prio. */
01129   inactivity = 0;
01130   inactive = NULL;
01131   for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
01132     if (pcb->prio <= prio &&
01133        pcb->prio <= mprio &&
01134        (u32_t)(tcp_ticks - pcb->tmr) >= inactivity) {
01135       inactivity = tcp_ticks - pcb->tmr;
01136       inactive = pcb;
01137       mprio = pcb->prio;
01138     }
01139   }
01140   if (inactive != NULL) {
01141     LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB %p (%"S32_F")\n",
01142            (void *)inactive, inactivity));
01143     tcp_abort(inactive);
01144   }
01145 }
01146 
01151 static void
01152 tcp_kill_timewait(void)
01153 {
01154   struct tcp_pcb *pcb, *inactive;
01155   u32_t inactivity;
01156 
01157   inactivity = 0;
01158   inactive = NULL;
01159   /* Go through the list of TIME_WAIT pcbs and get the oldest pcb. */
01160   for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
01161     if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) {
01162       inactivity = tcp_ticks - pcb->tmr;
01163       inactive = pcb;
01164     }
01165   }
01166   if (inactive != NULL) {
01167     LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB %p (%"S32_F")\n",
01168            (void *)inactive, inactivity));
01169     tcp_abort(inactive);
01170   }
01171 }
01172 
01179 struct tcp_pcb *
01180 tcp_alloc(u8_t prio)
01181 {
01182   struct tcp_pcb *pcb;
01183   u32_t iss;
01184   
01185   pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
01186   if (pcb == NULL) {
01187     /* Try killing oldest connection in TIME-WAIT. */
01188     LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest TIME-WAIT connection\n"));
01189     tcp_kill_timewait();
01190     /* Try to allocate a tcp_pcb again. */
01191     pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
01192     if (pcb == NULL) {
01193       /* Try killing active connections with lower priority than the new one. */
01194       LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing connection with prio lower than %d\n", prio));
01195       tcp_kill_prio(prio);
01196       /* Try to allocate a tcp_pcb again. */
01197       pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
01198       if (pcb != NULL) {
01199         /* adjust err stats: memp_malloc failed twice before */
01200         MEMP_STATS_DEC(err, MEMP_TCP_PCB);
01201       }
01202     }
01203     if (pcb != NULL) {
01204       /* adjust err stats: timewait PCB was freed above */
01205       MEMP_STATS_DEC(err, MEMP_TCP_PCB);
01206     }
01207   }
01208   if (pcb != NULL) {
01209     memset(pcb, 0, sizeof(struct tcp_pcb));
01210     pcb->prio = prio;
01211     pcb->snd_buf = TCP_SND_BUF;
01212     pcb->snd_queuelen = 0;
01213     pcb->rcv_wnd = TCP_WND;
01214     pcb->rcv_ann_wnd = TCP_WND;
01215     pcb->tos = 0;
01216     pcb->ttl = TCP_TTL;
01217     /* As initial send MSS, we use TCP_MSS but limit it to 536.
01218        The send MSS is updated when an MSS option is received. */
01219     pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS;
01220     pcb->rto = 3000 / TCP_SLOW_INTERVAL;
01221     pcb->sa = 0;
01222     pcb->sv = 3000 / TCP_SLOW_INTERVAL;
01223     pcb->rtime = -1;
01224     pcb->cwnd = 1;
01225     iss = tcp_next_iss();
01226     pcb->snd_wl2 = iss;
01227     pcb->snd_nxt = iss;
01228     pcb->lastack = iss;
01229     pcb->snd_lbb = iss;   
01230     pcb->tmr = tcp_ticks;
01231 
01232     pcb->polltmr = 0;
01233 
01234 #if LWIP_CALLBACK_API
01235     pcb->recv = tcp_recv_null;
01236 #endif /* LWIP_CALLBACK_API */  
01237     
01238     /* Init KEEPALIVE timer */
01239     pcb->keep_idle  = TCP_KEEPIDLE_DEFAULT;
01240     
01241 #if LWIP_TCP_KEEPALIVE
01242     pcb->keep_intvl = TCP_KEEPINTVL_DEFAULT;
01243     pcb->keep_cnt   = TCP_KEEPCNT_DEFAULT;
01244 #endif /* LWIP_TCP_KEEPALIVE */
01245 
01246     pcb->keep_cnt_sent = 0;
01247   }
01248   return pcb;
01249 }
01250 
01263 struct tcp_pcb *
01264 tcp_new(void)
01265 {
01266   return tcp_alloc(TCP_PRIO_NORMAL);
01267 }
01268 
01276 void
01277 tcp_arg(struct tcp_pcb *pcb, void *arg)
01278 {  
01279   pcb->callback_arg = arg;
01280 }
01281 #if LWIP_CALLBACK_API
01282 
01290 void
01291 tcp_recv(struct tcp_pcb *pcb, tcp_recv_fn recv)
01292 {
01293   pcb->recv = recv;
01294 }
01295 
01303 void
01304 tcp_sent(struct tcp_pcb *pcb, tcp_sent_fn sent)
01305 {
01306   pcb->sent = sent;
01307 }
01308 
01317 void
01318 tcp_err(struct tcp_pcb *pcb, tcp_err_fn err)
01319 {
01320   pcb->errf = err;
01321 }
01322 
01331 void
01332 tcp_accept(struct tcp_pcb *pcb, tcp_accept_fn accept)
01333 {
01334   pcb->accept = accept;
01335 }
01336 #endif /* LWIP_CALLBACK_API */
01337 
01338 
01345 void
01346 tcp_poll(struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval)
01347 {
01348 #if LWIP_CALLBACK_API
01349   pcb->poll = poll;
01350 #else /* LWIP_CALLBACK_API */  
01351   LWIP_UNUSED_ARG(poll);
01352 #endif /* LWIP_CALLBACK_API */  
01353   pcb->pollinterval = interval;
01354 }
01355 
01362 void
01363 tcp_pcb_purge(struct tcp_pcb *pcb)
01364 {
01365   if (pcb->state != CLOSED &&
01366      pcb->state != TIME_WAIT &&
01367      pcb->state != LISTEN) {
01368 
01369     LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge\n"));
01370 
01371 #if TCP_LISTEN_BACKLOG
01372     if (pcb->state == SYN_RCVD) {
01373       /* Need to find the corresponding listen_pcb and decrease its accepts_pending */
01374       struct tcp_pcb_listen *lpcb;
01375       LWIP_ASSERT("tcp_pcb_purge: pcb->state == SYN_RCVD but tcp_listen_pcbs is NULL",
01376         tcp_listen_pcbs.listen_pcbs != NULL);
01377       for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
01378         if ((lpcb->local_port == pcb->local_port) &&
01379             (ip_addr_isany(&lpcb->local_ip) ||
01380              ip_addr_cmp(&pcb->local_ip, &lpcb->local_ip))) {
01381             /* port and address of the listen pcb match the timed-out pcb */
01382             LWIP_ASSERT("tcp_pcb_purge: listen pcb does not have accepts pending",
01383               lpcb->accepts_pending > 0);
01384             lpcb->accepts_pending--;
01385             break;
01386           }
01387       }
01388     }
01389 #endif /* TCP_LISTEN_BACKLOG */
01390 
01391 
01392     if (pcb->refused_data != NULL) {
01393       LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->refused_data\n"));
01394       pbuf_free(pcb->refused_data);
01395       pcb->refused_data = NULL;
01396     }
01397     if (pcb->unsent != NULL) {
01398       LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: not all data sent\n"));
01399     }
01400     if (pcb->unacked != NULL) {
01401       LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->unacked\n"));
01402     }
01403 #if TCP_QUEUE_OOSEQ
01404     if (pcb->ooseq != NULL) {
01405       LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n"));
01406     }
01407     tcp_segs_free(pcb->ooseq);
01408     pcb->ooseq = NULL;
01409 #endif /* TCP_QUEUE_OOSEQ */
01410 
01411     /* Stop the retransmission timer as it will expect data on unacked
01412        queue if it fires */
01413     pcb->rtime = -1;
01414 
01415     tcp_segs_free(pcb->unsent);
01416     tcp_segs_free(pcb->unacked);
01417     pcb->unacked = pcb->unsent = NULL;
01418 #if TCP_OVERSIZE
01419     pcb->unsent_oversize = 0;
01420 #endif /* TCP_OVERSIZE */
01421   }
01422 }
01423 
01430 void
01431 tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb)
01432 {
01433   TCP_RMV(pcblist, pcb);
01434 
01435   tcp_pcb_purge(pcb);
01436   
01437   /* if there is an outstanding delayed ACKs, send it */
01438   if (pcb->state != TIME_WAIT &&
01439      pcb->state != LISTEN &&
01440      pcb->flags & TF_ACK_DELAY) {
01441     pcb->flags |= TF_ACK_NOW;
01442     tcp_output(pcb);
01443   }
01444 
01445   if (pcb->state != LISTEN) {
01446     LWIP_ASSERT("unsent segments leaking", pcb->unsent == NULL);
01447     LWIP_ASSERT("unacked segments leaking", pcb->unacked == NULL);
01448 #if TCP_QUEUE_OOSEQ
01449     LWIP_ASSERT("ooseq segments leaking", pcb->ooseq == NULL);
01450 #endif /* TCP_QUEUE_OOSEQ */
01451   }
01452 
01453   pcb->state = CLOSED;
01454 
01455   LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane());
01456 }
01457 
01463 u32_t
01464 tcp_next_iss(void)
01465 {
01466   static u32_t iss = 6510;
01467   
01468   iss += tcp_ticks;       /* XXX */
01469   return iss;
01470 }
01471 
01472 #if TCP_CALCULATE_EFF_SEND_MSS
01473 
01478 u16_t
01479 tcp_eff_send_mss(u16_t sendmss, ip_addr_t *addr)
01480 {
01481   u16_t mss_s;
01482   struct netif *outif;
01483 
01484   outif = ip_route(addr);
01485   if ((outif != NULL) && (outif->mtu != 0)) {
01486     mss_s = outif->mtu - IP_HLEN - TCP_HLEN;
01487     /* RFC 1122, chap 4.2.2.6:
01488      * Eff.snd.MSS = min(SendMSS+20, MMS_S) - TCPhdrsize - IPoptionsize
01489      * We correct for TCP options in tcp_write(), and don't support IP options.
01490      */
01491     sendmss = LWIP_MIN(sendmss, mss_s);
01492   }
01493   return sendmss;
01494 }
01495 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
01496 
01497 const char*
01498 tcp_debug_state_str(enum tcp_state s)
01499 {
01500   return tcp_state_str[s];
01501 }
01502 
01503 #if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG
01504 
01509 void
01510 tcp_debug_print(struct tcp_hdr *tcphdr)
01511 {
01512   LWIP_DEBUGF(TCP_DEBUG, ("TCP header:\n"));
01513   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
01514   LWIP_DEBUGF(TCP_DEBUG, ("|    %5"U16_F"      |    %5"U16_F"      | (src port, dest port)\n",
01515          ntohs(tcphdr->src), ntohs(tcphdr->dest)));
01516   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
01517   LWIP_DEBUGF(TCP_DEBUG, ("|           %010"U32_F"          | (seq no)\n",
01518           ntohl(tcphdr->seqno)));
01519   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
01520   LWIP_DEBUGF(TCP_DEBUG, ("|           %010"U32_F"          | (ack no)\n",
01521          ntohl(tcphdr->ackno)));
01522   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
01523   LWIP_DEBUGF(TCP_DEBUG, ("| %2"U16_F" |   |%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"|     %5"U16_F"     | (hdrlen, flags (",
01524        TCPH_HDRLEN(tcphdr),
01525          TCPH_FLAGS(tcphdr) >> 5 & 1,
01526          TCPH_FLAGS(tcphdr) >> 4 & 1,
01527          TCPH_FLAGS(tcphdr) >> 3 & 1,
01528          TCPH_FLAGS(tcphdr) >> 2 & 1,
01529          TCPH_FLAGS(tcphdr) >> 1 & 1,
01530          TCPH_FLAGS(tcphdr) & 1,
01531          ntohs(tcphdr->wnd)));
01532   tcp_debug_print_flags(TCPH_FLAGS(tcphdr));
01533   LWIP_DEBUGF(TCP_DEBUG, ("), win)\n"));
01534   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
01535   LWIP_DEBUGF(TCP_DEBUG, ("|    0x%04"X16_F"     |     %5"U16_F"     | (chksum, urgp)\n",
01536          ntohs(tcphdr->chksum), ntohs(tcphdr->urgp)));
01537   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
01538 }
01539 
01545 void
01546 tcp_debug_print_state(enum tcp_state s)
01547 {
01548   LWIP_DEBUGF(TCP_DEBUG, ("State: %s\n", tcp_state_str[s]));
01549 }
01550 
01556 void
01557 tcp_debug_print_flags(u8_t flags)
01558 {
01559   if (flags & TCP_FIN) {
01560     LWIP_DEBUGF(TCP_DEBUG, ("FIN "));
01561   }
01562   if (flags & TCP_SYN) {
01563     LWIP_DEBUGF(TCP_DEBUG, ("SYN "));
01564   }
01565   if (flags & TCP_RST) {
01566     LWIP_DEBUGF(TCP_DEBUG, ("RST "));
01567   }
01568   if (flags & TCP_PSH) {
01569     LWIP_DEBUGF(TCP_DEBUG, ("PSH "));
01570   }
01571   if (flags & TCP_ACK) {
01572     LWIP_DEBUGF(TCP_DEBUG, ("ACK "));
01573   }
01574   if (flags & TCP_URG) {
01575     LWIP_DEBUGF(TCP_DEBUG, ("URG "));
01576   }
01577   if (flags & TCP_ECE) {
01578     LWIP_DEBUGF(TCP_DEBUG, ("ECE "));
01579   }
01580   if (flags & TCP_CWR) {
01581     LWIP_DEBUGF(TCP_DEBUG, ("CWR "));
01582   }
01583   LWIP_DEBUGF(TCP_DEBUG, ("\n"));
01584 }
01585 
01589 void
01590 tcp_debug_print_pcbs(void)
01591 {
01592   struct tcp_pcb *pcb;
01593   LWIP_DEBUGF(TCP_DEBUG, ("Active PCB states:\n"));
01594   for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
01595     LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
01596                        pcb->local_port, pcb->remote_port,
01597                        pcb->snd_nxt, pcb->rcv_nxt));
01598     tcp_debug_print_state(pcb->state);
01599   }    
01600   LWIP_DEBUGF(TCP_DEBUG, ("Listen PCB states:\n"));
01601   for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) {
01602     LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
01603                        pcb->local_port, pcb->remote_port,
01604                        pcb->snd_nxt, pcb->rcv_nxt));
01605     tcp_debug_print_state(pcb->state);
01606   }    
01607   LWIP_DEBUGF(TCP_DEBUG, ("TIME-WAIT PCB states:\n"));
01608   for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
01609     LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
01610                        pcb->local_port, pcb->remote_port,
01611                        pcb->snd_nxt, pcb->rcv_nxt));
01612     tcp_debug_print_state(pcb->state);
01613   }    
01614 }
01615 
01619 s16_t
01620 tcp_pcbs_sane(void)
01621 {
01622   struct tcp_pcb *pcb;
01623   for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
01624     LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != CLOSED", pcb->state != CLOSED);
01625     LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != LISTEN", pcb->state != LISTEN);
01626     LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
01627   }
01628   for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
01629     LWIP_ASSERT("tcp_pcbs_sane: tw pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
01630   }
01631   return 1;
01632 }
01633 #endif /* TCP_DEBUG */
01634 
01635 #endif /* LWIP_TCP */

Generated on Sun May 27 2012 04:17:11 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.