Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Release 1.0
[palacios.git] / geekos / src / lwip / core / tcp.c
1 /**
2  * @file
3  * Transmission Control Protocol for IP
4  *
5  * This file contains common functions for the TCP implementation, such as functinos
6  * for manipulating the data structures and the TCP timer functions. TCP functions
7  * related to input and output is found in tcp_in.c and tcp_out.c respectively.
8  *
9  */
10
11 /*
12  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
13  * All rights reserved. 
14  * 
15  * Redistribution and use in source and binary forms, with or without modification, 
16  * are permitted provided that the following conditions are met:
17  *
18  * 1. Redistributions of source code must retain the above copyright notice,
19  *    this list of conditions and the following disclaimer.
20  * 2. Redistributions in binary form must reproduce the above copyright notice,
21  *    this list of conditions and the following disclaimer in the documentation
22  *    and/or other materials provided with the distribution.
23  * 3. The name of the author may not be used to endorse or promote products
24  *    derived from this software without specific prior written permission. 
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
27  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
28  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
29  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
30  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
31  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
34  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
35  * OF SUCH DAMAGE.
36  *
37  * This file is part of the lwIP TCP/IP stack.
38  * 
39  * Author: Adam Dunkels <adam@sics.se>
40  *
41  */
42
43 #include "lwip/opt.h"
44
45 #if LWIP_TCP /* don't build if not configured for use in lwipopts.h */
46
47 #include "lwip/def.h"
48 #include "lwip/mem.h"
49 #include "lwip/memp.h"
50 #include "lwip/snmp.h"
51 #include "lwip/tcp.h"
52
53 #include <string.h>
54
55 /* Incremented every coarse grained timer shot (typically every 500 ms). */
56 u32_t tcp_ticks;
57 const u8_t tcp_backoff[13] =
58     { 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7};
59  /* Times per slowtmr hits */
60 const u8_t tcp_persist_backoff[7] = { 3, 6, 12, 24, 48, 96, 120 };
61
62 /* The TCP PCB lists. */
63
64 /** List of all TCP PCBs bound but not yet (connected || listening) */
65 struct tcp_pcb *tcp_bound_pcbs;  
66 /** List of all TCP PCBs in LISTEN state */
67 union tcp_listen_pcbs_t tcp_listen_pcbs;
68 /** List of all TCP PCBs that are in a state in which
69  * they accept or send data. */
70 struct tcp_pcb *tcp_active_pcbs;  
71 /** List of all TCP PCBs in TIME-WAIT state */
72 struct tcp_pcb *tcp_tw_pcbs;
73
74 struct tcp_pcb *tcp_tmp_pcb;
75
76 static u8_t tcp_timer;
77 static u16_t tcp_new_port(void);
78
79 /**
80  * Called periodically to dispatch TCP timers.
81  *
82  */
83 void
84 tcp_tmr(void)
85 {
86   /* Call tcp_fasttmr() every 250 ms */
87   tcp_fasttmr();
88
89   if (++tcp_timer & 1) {
90     /* Call tcp_tmr() every 500 ms, i.e., every other timer
91        tcp_tmr() is called. */
92     tcp_slowtmr();
93   }
94 }
95
96 /**
97  * Closes the connection held by the PCB.
98  *
99  * Listening pcbs are freed and may not be referenced any more.
100  * Connection pcbs are freed if not yet connected and may not be referenced
101  * any more. If a connection is established (at least SYN received or in
102  * a closing state), the connection is closed, and put in a closing state.
103  * The pcb is then automatically freed in tcp_slowtmr(). It is therefore
104  * unsafe to reference it.
105  *
106  * @param pcb the tcp_pcb to close
107  * @return ERR_OK if connection has been closed
108  *         another err_t if closing failed and pcb is not freed
109  */
110 err_t
111 tcp_close(struct tcp_pcb *pcb)
112 {
113   err_t err;
114
115 #if TCP_DEBUG
116   LWIP_DEBUGF(TCP_DEBUG, ("tcp_close: closing in "));
117   tcp_debug_print_state(pcb->state);
118 #endif /* TCP_DEBUG */
119
120   switch (pcb->state) {
121   case CLOSED:
122     /* Closing a pcb in the CLOSED state might seem erroneous,
123      * however, it is in this state once allocated and as yet unused
124      * and the user needs some way to free it should the need arise.
125      * Calling tcp_close() with a pcb that has already been closed, (i.e. twice)
126      * or for a pcb that has been used and then entered the CLOSED state 
127      * is erroneous, but this should never happen as the pcb has in those cases
128      * been freed, and so any remaining handles are bogus. */
129     err = ERR_OK;
130     TCP_RMV(&tcp_bound_pcbs, pcb);
131     memp_free(MEMP_TCP_PCB, pcb);
132     pcb = NULL;
133     break;
134   case LISTEN:
135     err = ERR_OK;
136     tcp_pcb_remove((struct tcp_pcb **)&tcp_listen_pcbs.pcbs, pcb);
137     memp_free(MEMP_TCP_PCB_LISTEN, pcb);
138     pcb = NULL;
139     break;
140   case SYN_SENT:
141     err = ERR_OK;
142     tcp_pcb_remove(&tcp_active_pcbs, pcb);
143     memp_free(MEMP_TCP_PCB, pcb);
144     pcb = NULL;
145     snmp_inc_tcpattemptfails();
146     break;
147   case SYN_RCVD:
148     err = tcp_send_ctrl(pcb, TCP_FIN);
149     if (err == ERR_OK) {
150       snmp_inc_tcpattemptfails();
151       pcb->state = FIN_WAIT_1;
152     }
153     break;
154   case ESTABLISHED:
155     err = tcp_send_ctrl(pcb, TCP_FIN);
156     if (err == ERR_OK) {
157       snmp_inc_tcpestabresets();
158       pcb->state = FIN_WAIT_1;
159     }
160     break;
161   case CLOSE_WAIT:
162     err = tcp_send_ctrl(pcb, TCP_FIN);
163     if (err == ERR_OK) {
164       snmp_inc_tcpestabresets();
165       pcb->state = LAST_ACK;
166     }
167     break;
168   default:
169     /* Has already been closed, do nothing. */
170     err = ERR_OK;
171     pcb = NULL;
172     break;
173   }
174
175   if (pcb != NULL && err == ERR_OK) {
176     /* To ensure all data has been sent when tcp_close returns, we have
177        to make sure tcp_output doesn't fail.
178        Since we don't really have to ensure all data has been sent when tcp_close
179        returns (unsent data is sent from tcp timer functions, also), we don't care
180        for the return value of tcp_output for now. */
181     /* @todo: When implementing SO_LINGER, this must be changed somehow:
182        If SOF_LINGER is set, the data should be sent when tcp_close returns. */
183     tcp_output(pcb);
184   }
185   return err;
186 }
187
188 /**
189  * Aborts a connection by sending a RST to the remote host and deletes
190  * the local protocol control block. This is done when a connection is
191  * killed because of shortage of memory.
192  *
193  * @param pcb the tcp_pcb to abort
194  */
195 void
196 tcp_abort(struct tcp_pcb *pcb)
197 {
198   u32_t seqno, ackno;
199   u16_t remote_port, local_port;
200   struct ip_addr remote_ip, local_ip;
201 #if LWIP_CALLBACK_API  
202   void (* errf)(void *arg, err_t err);
203 #endif /* LWIP_CALLBACK_API */
204   void *errf_arg;
205
206   
207   /* Figure out on which TCP PCB list we are, and remove us. If we
208      are in an active state, call the receive function associated with
209      the PCB with a NULL argument, and send an RST to the remote end. */
210   if (pcb->state == TIME_WAIT) {
211     tcp_pcb_remove(&tcp_tw_pcbs, pcb);
212     memp_free(MEMP_TCP_PCB, pcb);
213   } else {
214     seqno = pcb->snd_nxt;
215     ackno = pcb->rcv_nxt;
216     ip_addr_set(&local_ip, &(pcb->local_ip));
217     ip_addr_set(&remote_ip, &(pcb->remote_ip));
218     local_port = pcb->local_port;
219     remote_port = pcb->remote_port;
220 #if LWIP_CALLBACK_API
221     errf = pcb->errf;
222 #endif /* LWIP_CALLBACK_API */
223     errf_arg = pcb->callback_arg;
224     tcp_pcb_remove(&tcp_active_pcbs, pcb);
225     if (pcb->unacked != NULL) {
226       tcp_segs_free(pcb->unacked);
227     }
228     if (pcb->unsent != NULL) {
229       tcp_segs_free(pcb->unsent);
230     }
231 #if TCP_QUEUE_OOSEQ    
232     if (pcb->ooseq != NULL) {
233       tcp_segs_free(pcb->ooseq);
234     }
235 #endif /* TCP_QUEUE_OOSEQ */
236     memp_free(MEMP_TCP_PCB, pcb);
237     TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT);
238     LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abort: sending RST\n"));
239     tcp_rst(seqno, ackno, &local_ip, &remote_ip, local_port, remote_port);
240   }
241 }
242
243 /**
244  * Binds the connection to a local portnumber and IP address. If the
245  * IP address is not given (i.e., ipaddr == NULL), the IP address of
246  * the outgoing network interface is used instead.
247  *
248  * @param pcb the tcp_pcb to bind (no check is done whether this pcb is
249  *        already bound!)
250  * @param ipaddr the local ip address to bind to (use IP_ADDR_ANY to bind
251  *        to any local address
252  * @param port the local port to bind to
253  * @return ERR_USE if the port is already in use
254  *         ERR_OK if bound
255  */
256 err_t
257 tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
258 {
259   struct tcp_pcb *cpcb;
260
261   LWIP_ERROR("tcp_connect: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_ISCONN);
262
263   if (port == 0) {
264     port = tcp_new_port();
265   }
266   /* Check if the address already is in use. */
267   /* Check the listen pcbs. */
268   for(cpcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs;
269       cpcb != NULL; cpcb = cpcb->next) {
270     if (cpcb->local_port == port) {
271       if (ip_addr_isany(&(cpcb->local_ip)) ||
272           ip_addr_isany(ipaddr) ||
273           ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {
274         return ERR_USE;
275       }
276     }
277   }
278   /* Check the connected pcbs. */
279   for(cpcb = tcp_active_pcbs;
280       cpcb != NULL; cpcb = cpcb->next) {
281     if (cpcb->local_port == port) {
282       if (ip_addr_isany(&(cpcb->local_ip)) ||
283           ip_addr_isany(ipaddr) ||
284           ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {
285         return ERR_USE;
286       }
287     }
288   }
289   /* Check the bound, not yet connected pcbs. */
290   for(cpcb = tcp_bound_pcbs; cpcb != NULL; cpcb = cpcb->next) {
291     if (cpcb->local_port == port) {
292       if (ip_addr_isany(&(cpcb->local_ip)) ||
293           ip_addr_isany(ipaddr) ||
294           ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {
295         return ERR_USE;
296       }
297     }
298   }
299   /* @todo: until SO_REUSEADDR is implemented (see task #6995 on savannah),
300    * we have to check the pcbs in TIME-WAIT state, also: */
301   for(cpcb = tcp_tw_pcbs; cpcb != NULL; cpcb = cpcb->next) {
302     if (cpcb->local_port == port) {
303       if (ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {
304         return ERR_USE;
305       }
306     }
307   }
308
309   if (!ip_addr_isany(ipaddr)) {
310     pcb->local_ip = *ipaddr;
311   }
312   pcb->local_port = port;
313   TCP_REG(&tcp_bound_pcbs, pcb);
314   LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %"U16_F"\n", port));
315   return ERR_OK;
316 }
317 #if LWIP_CALLBACK_API
318 /**
319  * Default accept callback if no accept callback is specified by the user.
320  */
321 static err_t
322 tcp_accept_null(void *arg, struct tcp_pcb *pcb, err_t err)
323 {
324   LWIP_UNUSED_ARG(arg);
325   LWIP_UNUSED_ARG(pcb);
326   LWIP_UNUSED_ARG(err);
327
328   return ERR_ABRT;
329 }
330 #endif /* LWIP_CALLBACK_API */
331
332 /**
333  * Set the state of the connection to be LISTEN, which means that it
334  * is able to accept incoming connections. The protocol control block
335  * is reallocated in order to consume less memory. Setting the
336  * connection to LISTEN is an irreversible process.
337  *
338  * @param pcb the original tcp_pcb
339  * @param backlog the incoming connections queue limit
340  * @return tcp_pcb used for listening, consumes less memory.
341  *
342  * @note The original tcp_pcb is freed. This function therefore has to be
343  *       called like this:
344  *             tpcb = tcp_listen(tpcb);
345  */
346 struct tcp_pcb *
347 tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
348 {
349   struct tcp_pcb_listen *lpcb;
350
351   LWIP_UNUSED_ARG(backlog);
352   LWIP_ERROR("tcp_listen: pcb already connected", pcb->state == CLOSED, return NULL);
353
354   /* already listening? */
355   if (pcb->state == LISTEN) {
356     return pcb;
357   }
358   lpcb = memp_malloc(MEMP_TCP_PCB_LISTEN);
359   if (lpcb == NULL) {
360     return NULL;
361   }
362   lpcb->callback_arg = pcb->callback_arg;
363   lpcb->local_port = pcb->local_port;
364   lpcb->state = LISTEN;
365   lpcb->so_options = pcb->so_options;
366   lpcb->so_options |= SOF_ACCEPTCONN;
367   lpcb->ttl = pcb->ttl;
368   lpcb->tos = pcb->tos;
369   ip_addr_set(&lpcb->local_ip, &pcb->local_ip);
370   TCP_RMV(&tcp_bound_pcbs, pcb);
371   memp_free(MEMP_TCP_PCB, pcb);
372 #if LWIP_CALLBACK_API
373   lpcb->accept = tcp_accept_null;
374 #endif /* LWIP_CALLBACK_API */
375 #if TCP_LISTEN_BACKLOG
376   lpcb->accepts_pending = 0;
377   lpcb->backlog = (backlog ? backlog : 1);
378 #endif /* TCP_LISTEN_BACKLOG */
379   TCP_REG(&tcp_listen_pcbs.listen_pcbs, lpcb);
380   return (struct tcp_pcb *)lpcb;
381 }
382
383 /**
384  * This function should be called by the application when it has
385  * processed the data. The purpose is to advertise a larger window
386  * when the data has been processed.
387  *
388  * @param pcb the tcp_pcb for which data is read
389  * @param len the amount of bytes that have been read by the application
390  */
391 void
392 tcp_recved(struct tcp_pcb *pcb, u16_t len)
393 {
394   if ((u32_t)pcb->rcv_wnd + len > TCP_WND) {
395     pcb->rcv_wnd = TCP_WND;
396     pcb->rcv_ann_wnd = TCP_WND;
397   } else {
398     pcb->rcv_wnd += len;
399     if (pcb->rcv_wnd >= pcb->mss) {
400       pcb->rcv_ann_wnd = pcb->rcv_wnd;
401     }
402   }
403
404   if (!(pcb->flags & TF_ACK_DELAY) &&
405      !(pcb->flags & TF_ACK_NOW)) {
406     /*
407      * We send an ACK here (if one is not already pending, hence
408      * the above tests) as tcp_recved() implies that the application
409      * has processed some data, and so we can open the receiver's
410      * window to allow more to be transmitted.  This could result in
411      * two ACKs being sent for each received packet in some limited cases
412      * (where the application is only receiving data, and is slow to
413      * process it) but it is necessary to guarantee that the sender can
414      * continue to transmit.
415      */
416     tcp_ack(pcb);
417   } 
418   else if (pcb->flags & TF_ACK_DELAY && pcb->rcv_wnd >= TCP_WND/2) {
419     /* If we can send a window update such that there is a full
420      * segment available in the window, do so now.  This is sort of
421      * nagle-like in its goals, and tries to hit a compromise between
422      * sending acks each time the window is updated, and only sending
423      * window updates when a timer expires.  The "threshold" used
424      * above (currently TCP_WND/2) can be tuned to be more or less
425      * aggressive  */
426     tcp_ack_now(pcb);
427   }
428
429   LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: recveived %"U16_F" bytes, wnd %"U16_F" (%"U16_F").\n",
430          len, pcb->rcv_wnd, TCP_WND - pcb->rcv_wnd));
431 }
432
433 /**
434  * A nastly hack featuring 'goto' statements that allocates a
435  * new TCP local port.
436  *
437  * @return a new (free) local TCP port number
438  */
439 static u16_t
440 tcp_new_port(void)
441 {
442   struct tcp_pcb *pcb;
443 #ifndef TCP_LOCAL_PORT_RANGE_START
444 #define TCP_LOCAL_PORT_RANGE_START 4096
445 #define TCP_LOCAL_PORT_RANGE_END   0x7fff
446 #endif
447   static u16_t port = TCP_LOCAL_PORT_RANGE_START;
448   
449  again:
450   if (++port > TCP_LOCAL_PORT_RANGE_END) {
451     port = TCP_LOCAL_PORT_RANGE_START;
452   }
453   
454   for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
455     if (pcb->local_port == port) {
456       goto again;
457     }
458   }
459   for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
460     if (pcb->local_port == port) {
461       goto again;
462     }
463   }
464   for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) {
465     if (pcb->local_port == port) {
466       goto again;
467     }
468   }
469   return port;
470 }
471
472 /**
473  * Connects to another host. The function given as the "connected"
474  * argument will be called when the connection has been established.
475  *
476  * @param pcb the tcp_pcb used to establish the connection
477  * @param ipaddr the remote ip address to connect to
478  * @param port the remote tcp port to connect to
479  * @param connected callback function to call when connected (or on error)
480  * @return ERR_VAL if invalid arguments are given
481  *         ERR_OK if connect request has been sent
482  *         other err_t values if connect request couldn't be sent
483  */
484 err_t
485 tcp_connect(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port,
486       err_t (* connected)(void *arg, struct tcp_pcb *tpcb, err_t err))
487 {
488   u32_t optdata;
489   err_t ret;
490   u32_t iss;
491
492   LWIP_ERROR("tcp_connect: can only connected from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN);
493
494   LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port));
495   if (ipaddr != NULL) {
496     pcb->remote_ip = *ipaddr;
497   } else {
498     return ERR_VAL;
499   }
500   pcb->remote_port = port;
501   if (pcb->local_port == 0) {
502     pcb->local_port = tcp_new_port();
503   }
504   iss = tcp_next_iss();
505   pcb->rcv_nxt = 0;
506   pcb->snd_nxt = iss;
507   pcb->lastack = iss - 1;
508   pcb->snd_lbb = iss - 1;
509   pcb->rcv_wnd = TCP_WND;
510   pcb->rcv_ann_wnd = TCP_WND;
511   pcb->snd_wnd = TCP_WND;
512   /* The send MSS is updated when an MSS option is received. */
513   pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS;
514 #if TCP_CALCULATE_EFF_SEND_MSS
515   pcb->mss = tcp_eff_send_mss(pcb->mss, ipaddr);
516 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
517   pcb->cwnd = 1;
518   pcb->ssthresh = pcb->mss * 10;
519   pcb->state = SYN_SENT;
520 #if LWIP_CALLBACK_API  
521   pcb->connected = connected;
522 #endif /* LWIP_CALLBACK_API */
523   TCP_RMV(&tcp_bound_pcbs, pcb);
524   TCP_REG(&tcp_active_pcbs, pcb);
525
526   snmp_inc_tcpactiveopens();
527   
528   /* Build an MSS option */
529   optdata = TCP_BUILD_MSS_OPTION();
530
531   ret = tcp_enqueue(pcb, NULL, 0, TCP_SYN, 0, (u8_t *)&optdata, 4);
532   if (ret == ERR_OK) { 
533     tcp_output(pcb);
534   }
535   return ret;
536
537
538 /**
539  * Called every 500 ms and implements the retransmission timer and the timer that
540  * removes PCBs that have been in TIME-WAIT for enough time. It also increments
541  * various timers such as the inactivity timer in each PCB.
542  *
543  * Automatically called from tcp_tmr().
544  */
545 void
546 tcp_slowtmr(void)
547 {
548   struct tcp_pcb *pcb, *pcb2, *prev;
549   u16_t eff_wnd;
550   u8_t pcb_remove;      /* flag if a PCB should be removed */
551   err_t err;
552
553   err = ERR_OK;
554
555   ++tcp_ticks;
556
557   /* Steps through all of the active PCBs. */
558   prev = NULL;
559   pcb = tcp_active_pcbs;
560   if (pcb == NULL) {
561     LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n"));
562   }
563   while (pcb != NULL) {
564     LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb\n"));
565     LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED);
566     LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN);
567     LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT);
568
569     pcb_remove = 0;
570
571     if (pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) {
572       ++pcb_remove;
573       LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n"));
574     }
575     else if (pcb->nrtx == TCP_MAXRTX) {
576       ++pcb_remove;
577       LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n"));
578     } else {
579       if (pcb->persist_backoff > 0) {
580         /* If snd_wnd is zero, use persist timer to send 1 byte probes
581          * instead of using the standard retransmission mechanism. */
582         pcb->persist_cnt++;
583         if (pcb->persist_cnt >= tcp_persist_backoff[pcb->persist_backoff-1]) {
584           pcb->persist_cnt = 0;
585           if (pcb->persist_backoff < sizeof(tcp_persist_backoff)) {
586             pcb->persist_backoff++;
587           }
588           tcp_zero_window_probe(pcb);
589         }
590       } else {
591         /* Increase the retransmission timer if it is running */
592         if(pcb->rtime >= 0)
593           ++pcb->rtime;
594
595         if (pcb->unacked != NULL && pcb->rtime >= pcb->rto) {
596           /* Time for a retransmission. */
597           LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %"S16_F
598                                       " pcb->rto %"S16_F"\n",
599                                       pcb->rtime, pcb->rto));
600
601           /* Double retransmission time-out unless we are trying to
602            * connect to somebody (i.e., we are in SYN_SENT). */
603           if (pcb->state != SYN_SENT) {
604             pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx];
605           }
606
607           /* Reset the retransmission timer. */
608           pcb->rtime = 0;
609
610           /* Reduce congestion window and ssthresh. */
611           eff_wnd = LWIP_MIN(pcb->cwnd, pcb->snd_wnd);
612           pcb->ssthresh = eff_wnd >> 1;
613           if (pcb->ssthresh < pcb->mss) {
614             pcb->ssthresh = pcb->mss * 2;
615           }
616           pcb->cwnd = pcb->mss;
617           LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: cwnd %"U16_F
618                                        " ssthresh %"U16_F"\n",
619                                        pcb->cwnd, pcb->ssthresh));
620  
621           /* The following needs to be called AFTER cwnd is set to one
622              mss - STJ */
623           tcp_rexmit_rto(pcb);
624         }
625       }
626     }
627     /* Check if this PCB has stayed too long in FIN-WAIT-2 */
628     if (pcb->state == FIN_WAIT_2) {
629       if ((u32_t)(tcp_ticks - pcb->tmr) >
630           TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) {
631         ++pcb_remove;
632         LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n"));
633       }
634     }
635
636     /* Check if KEEPALIVE should be sent */
637     if((pcb->so_options & SOF_KEEPALIVE) && 
638        ((pcb->state == ESTABLISHED) || 
639         (pcb->state == CLOSE_WAIT))) {
640 #if LWIP_TCP_KEEPALIVE
641       if((u32_t)(tcp_ticks - pcb->tmr) > 
642          (pcb->keep_idle + (pcb->keep_cnt*pcb->keep_intvl))
643          / TCP_SLOW_INTERVAL)
644 #else      
645       if((u32_t)(tcp_ticks - pcb->tmr) > 
646          (pcb->keep_idle + TCP_MAXIDLE) / TCP_SLOW_INTERVAL)
647 #endif /* LWIP_TCP_KEEPALIVE */
648       {
649         LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to %"U16_F".%"U16_F".%"U16_F".%"U16_F".\n",
650                                 ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
651                                 ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip)));
652         
653         tcp_abort(pcb);
654       }
655 #if LWIP_TCP_KEEPALIVE
656       else if((u32_t)(tcp_ticks - pcb->tmr) > 
657               (pcb->keep_idle + pcb->keep_cnt_sent * pcb->keep_intvl)
658               / TCP_SLOW_INTERVAL)
659 #else
660       else if((u32_t)(tcp_ticks - pcb->tmr) > 
661               (pcb->keep_idle + pcb->keep_cnt_sent * TCP_KEEPINTVL_DEFAULT) 
662               / TCP_SLOW_INTERVAL)
663 #endif /* LWIP_TCP_KEEPALIVE */
664       {
665         tcp_keepalive(pcb);
666         pcb->keep_cnt_sent++;
667       }
668     }
669
670     /* If this PCB has queued out of sequence data, but has been
671        inactive for too long, will drop the data (it will eventually
672        be retransmitted). */
673 #if TCP_QUEUE_OOSEQ    
674     if (pcb->ooseq != NULL &&
675         (u32_t)tcp_ticks - pcb->tmr >= pcb->rto * TCP_OOSEQ_TIMEOUT) {
676       tcp_segs_free(pcb->ooseq);
677       pcb->ooseq = NULL;
678       LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: dropping OOSEQ queued data\n"));
679     }
680 #endif /* TCP_QUEUE_OOSEQ */
681
682     /* Check if this PCB has stayed too long in SYN-RCVD */
683     if (pcb->state == SYN_RCVD) {
684       if ((u32_t)(tcp_ticks - pcb->tmr) >
685           TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) {
686         ++pcb_remove;
687         LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n"));
688       }
689     }
690
691     /* Check if this PCB has stayed too long in LAST-ACK */
692     if (pcb->state == LAST_ACK) {
693       if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {
694         ++pcb_remove;
695         LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in LAST-ACK\n"));
696       }
697     }
698
699     /* If the PCB should be removed, do it. */
700     if (pcb_remove) {
701       tcp_pcb_purge(pcb);      
702       /* Remove PCB from tcp_active_pcbs list. */
703       if (prev != NULL) {
704         LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs);
705         prev->next = pcb->next;
706       } else {
707         /* This PCB was the first. */
708         LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb);
709         tcp_active_pcbs = pcb->next;
710       }
711
712       TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_ABRT);
713
714       pcb2 = pcb->next;
715       memp_free(MEMP_TCP_PCB, pcb);
716       pcb = pcb2;
717     } else {
718
719       /* We check if we should poll the connection. */
720       ++pcb->polltmr;
721       if (pcb->polltmr >= pcb->pollinterval) {
722         pcb->polltmr = 0;
723         LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n"));
724         TCP_EVENT_POLL(pcb, err);
725         if (err == ERR_OK) {
726           tcp_output(pcb);
727         }
728       }
729       
730       prev = pcb;
731       pcb = pcb->next;
732     }
733   }
734
735   
736   /* Steps through all of the TIME-WAIT PCBs. */
737   prev = NULL;    
738   pcb = tcp_tw_pcbs;
739   while (pcb != NULL) {
740     LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
741     pcb_remove = 0;
742
743     /* Check if this PCB has stayed long enough in TIME-WAIT */
744     if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {
745       ++pcb_remove;
746     }
747     
748
749
750     /* If the PCB should be removed, do it. */
751     if (pcb_remove) {
752       tcp_pcb_purge(pcb);      
753       /* Remove PCB from tcp_tw_pcbs list. */
754       if (prev != NULL) {
755         LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs);
756         prev->next = pcb->next;
757       } else {
758         /* This PCB was the first. */
759         LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb);
760         tcp_tw_pcbs = pcb->next;
761       }
762       pcb2 = pcb->next;
763       memp_free(MEMP_TCP_PCB, pcb);
764       pcb = pcb2;
765     } else {
766       prev = pcb;
767       pcb = pcb->next;
768     }
769   }
770 }
771
772 /**
773  * Is called every TCP_FAST_INTERVAL (250 ms) and process data previously
774  * "refused" by upper layer (application) and sends delayed ACKs.
775  *
776  * Automatically called from tcp_tmr().
777  */
778 void
779 tcp_fasttmr(void)
780 {
781   struct tcp_pcb *pcb;
782
783   for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
784     /* If there is data which was previously "refused" by upper layer */
785     if (pcb->refused_data != NULL) {
786       /* Notify again application with data previously received. */
787       err_t err;
788       LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_fasttmr: notify kept packet\n"));
789       TCP_EVENT_RECV(pcb, pcb->refused_data, ERR_OK, err);
790       if (err == ERR_OK) {
791         pcb->refused_data = NULL;
792       }
793     }
794
795     /* send delayed ACKs */  
796     if (pcb->flags & TF_ACK_DELAY) {
797       LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n"));
798       tcp_ack_now(pcb);
799       pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
800     }
801   }
802 }
803
804 /**
805  * Deallocates a list of TCP segments (tcp_seg structures).
806  *
807  * @param seg tcp_seg list of TCP segments to free
808  * @return the number of pbufs that were deallocated
809  */
810 u8_t
811 tcp_segs_free(struct tcp_seg *seg)
812 {
813   u8_t count = 0;
814   struct tcp_seg *next;
815   while (seg != NULL) {
816     next = seg->next;
817     count += tcp_seg_free(seg);
818     seg = next;
819   }
820   return count;
821 }
822
823 /**
824  * Frees a TCP segment (tcp_seg structure).
825  *
826  * @param seg single tcp_seg to free
827  * @return the number of pbufs that were deallocated
828  */
829 u8_t
830 tcp_seg_free(struct tcp_seg *seg)
831 {
832   u8_t count = 0;
833   
834   if (seg != NULL) {
835     if (seg->p != NULL) {
836       count = pbuf_free(seg->p);
837 #if TCP_DEBUG
838       seg->p = NULL;
839 #endif /* TCP_DEBUG */
840     }
841     memp_free(MEMP_TCP_SEG, seg);
842   }
843   return count;
844 }
845
846 /**
847  * Sets the priority of a connection.
848  *
849  * @param pcb the tcp_pcb to manipulate
850  * @param prio new priority
851  */
852 void
853 tcp_setprio(struct tcp_pcb *pcb, u8_t prio)
854 {
855   pcb->prio = prio;
856 }
857 #if TCP_QUEUE_OOSEQ
858
859 /**
860  * Returns a copy of the given TCP segment.
861  * The pbuf and data are not copied, only the pointers
862  *
863  * @param seg the old tcp_seg
864  * @return a copy of seg
865  */ 
866 struct tcp_seg *
867 tcp_seg_copy(struct tcp_seg *seg)
868 {
869   struct tcp_seg *cseg;
870
871   cseg = memp_malloc(MEMP_TCP_SEG);
872   if (cseg == NULL) {
873     return NULL;
874   }
875   SMEMCPY((u8_t *)cseg, (const u8_t *)seg, sizeof(struct tcp_seg)); 
876   pbuf_ref(cseg->p);
877   return cseg;
878 }
879 #endif
880
881 #if LWIP_CALLBACK_API
882 /**
883  * Default receive callback that is called if the user didn't register
884  * a recv callback for the pcb.
885  */
886 static err_t
887 tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
888 {
889   arg = arg;
890   if (p != NULL) {
891     pbuf_free(p);
892   } else if (err == ERR_OK) {
893     return tcp_close(pcb);
894   }
895   return ERR_OK;
896 }
897 #endif /* LWIP_CALLBACK_API */
898
899 /**
900  * Kills the oldest active connection that has lower priority than prio.
901  *
902  * @param prio minimum priority
903  */
904 static void
905 tcp_kill_prio(u8_t prio)
906 {
907   struct tcp_pcb *pcb, *inactive;
908   u32_t inactivity;
909   u8_t mprio;
910
911
912   mprio = TCP_PRIO_MAX;
913   
914   /* We kill the oldest active connection that has lower priority than prio. */
915   inactivity = 0;
916   inactive = NULL;
917   for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
918     if (pcb->prio <= prio &&
919        pcb->prio <= mprio &&
920        (u32_t)(tcp_ticks - pcb->tmr) >= inactivity) {
921       inactivity = tcp_ticks - pcb->tmr;
922       inactive = pcb;
923       mprio = pcb->prio;
924     }
925   }
926   if (inactive != NULL) {
927     LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB %p (%"S32_F")\n",
928            (void *)inactive, inactivity));
929     tcp_abort(inactive);
930   }      
931 }
932
933 /**
934  * Kills the oldest connection that is in TIME_WAIT state.
935  * Called from tcp_alloc() if no more connections are available.
936  */
937 static void
938 tcp_kill_timewait(void)
939 {
940   struct tcp_pcb *pcb, *inactive;
941   u32_t inactivity;
942
943   inactivity = 0;
944   inactive = NULL;
945   /* Go through the list of TIME_WAIT pcbs and get the oldest pcb. */
946   for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
947     if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) {
948       inactivity = tcp_ticks - pcb->tmr;
949       inactive = pcb;
950     }
951   }
952   if (inactive != NULL) {
953     LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB %p (%"S32_F")\n",
954            (void *)inactive, inactivity));
955     tcp_abort(inactive);
956   }      
957 }
958
959 /**
960  * Allocate a new tcp_pcb structure.
961  *
962  * @param prio priority for the new pcb
963  * @return a new tcp_pcb that initially is in state CLOSED
964  */
965 struct tcp_pcb *
966 tcp_alloc(u8_t prio)
967 {
968   struct tcp_pcb *pcb;
969   u32_t iss;
970   
971   pcb = memp_malloc(MEMP_TCP_PCB);
972   if (pcb == NULL) {
973     /* Try killing oldest connection in TIME-WAIT. */
974     LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest TIME-WAIT connection\n"));
975     tcp_kill_timewait();
976     /* Try to allocate a tcp_pcb again. */
977     pcb = memp_malloc(MEMP_TCP_PCB);
978     if (pcb == NULL) {
979       /* Try killing active connections with lower priority than the new one. */
980       tcp_kill_prio(prio);
981       /* Try to allocate a tcp_pcb again. */
982       pcb = memp_malloc(MEMP_TCP_PCB);
983     }
984   }
985   if (pcb != NULL) {
986     memset(pcb, 0, sizeof(struct tcp_pcb));
987     pcb->prio = TCP_PRIO_NORMAL;
988     pcb->snd_buf = TCP_SND_BUF;
989     pcb->snd_queuelen = 0;
990     pcb->rcv_wnd = TCP_WND;
991     pcb->rcv_ann_wnd = TCP_WND;
992     pcb->tos = 0;
993     pcb->ttl = TCP_TTL;
994     /* The send MSS is updated when an MSS option is received. */
995     pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS;
996     pcb->rto = 3000 / TCP_SLOW_INTERVAL;
997     pcb->sa = 0;
998     pcb->sv = 3000 / TCP_SLOW_INTERVAL;
999     pcb->rtime = -1;
1000     pcb->cwnd = 1;
1001     iss = tcp_next_iss();
1002     pcb->snd_wl2 = iss;
1003     pcb->snd_nxt = iss;
1004     pcb->snd_max = iss;
1005     pcb->lastack = iss;
1006     pcb->snd_lbb = iss;   
1007     pcb->tmr = tcp_ticks;
1008
1009     pcb->polltmr = 0;
1010
1011 #if LWIP_CALLBACK_API
1012     pcb->recv = tcp_recv_null;
1013 #endif /* LWIP_CALLBACK_API */  
1014     
1015     /* Init KEEPALIVE timer */
1016     pcb->keep_idle  = TCP_KEEPIDLE_DEFAULT;
1017     
1018 #if LWIP_TCP_KEEPALIVE
1019     pcb->keep_intvl = TCP_KEEPINTVL_DEFAULT;
1020     pcb->keep_cnt   = TCP_KEEPCNT_DEFAULT;
1021 #endif /* LWIP_TCP_KEEPALIVE */
1022
1023     pcb->keep_cnt_sent = 0;
1024   }
1025   return pcb;
1026 }
1027
1028 /**
1029  * Creates a new TCP protocol control block but doesn't place it on
1030  * any of the TCP PCB lists.
1031  * The pcb is not put on any list until binding using tcp_bind().
1032  *
1033  * @internal: Maybe there should be a idle TCP PCB list where these
1034  * PCBs are put on. Port reservation using tcp_bind() is implemented but
1035  * allocated pcbs that are not bound can't be killed automatically if wanting
1036  * to allocate a pcb with higher prio (@see tcp_kill_prio())
1037  *
1038  * @return a new tcp_pcb that initially is in state CLOSED
1039  */
1040 struct tcp_pcb *
1041 tcp_new(void)
1042 {
1043   return tcp_alloc(TCP_PRIO_NORMAL);
1044 }
1045
1046 /**
1047  * Used to specify the argument that should be passed callback
1048  * functions.
1049  *
1050  * @param pcb tcp_pcb to set the callback argument
1051  * @param arg void pointer argument to pass to callback functions
1052  */ 
1053 void
1054 tcp_arg(struct tcp_pcb *pcb, void *arg)
1055 {  
1056   pcb->callback_arg = arg;
1057 }
1058 #if LWIP_CALLBACK_API
1059
1060 /**
1061  * Used to specify the function that should be called when a TCP
1062  * connection receives data.
1063  *
1064  * @param pcb tcp_pcb to set the recv callback
1065  * @param recv callback function to call for this pcb when data is received
1066  */ 
1067 void
1068 tcp_recv(struct tcp_pcb *pcb,
1069    err_t (* recv)(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err))
1070 {
1071   pcb->recv = recv;
1072 }
1073
1074 /**
1075  * Used to specify the function that should be called when TCP data
1076  * has been successfully delivered to the remote host.
1077  *
1078  * @param pcb tcp_pcb to set the sent callback
1079  * @param sent callback function to call for this pcb when data is successfully sent
1080  */ 
1081 void
1082 tcp_sent(struct tcp_pcb *pcb,
1083    err_t (* sent)(void *arg, struct tcp_pcb *tpcb, u16_t len))
1084 {
1085   pcb->sent = sent;
1086 }
1087
1088 /**
1089  * Used to specify the function that should be called when a fatal error
1090  * has occured on the connection.
1091  *
1092  * @param pcb tcp_pcb to set the err callback
1093  * @param errf callback function to call for this pcb when a fatal error
1094  *        has occured on the connection
1095  */ 
1096 void
1097 tcp_err(struct tcp_pcb *pcb,
1098    void (* errf)(void *arg, err_t err))
1099 {
1100   pcb->errf = errf;
1101 }
1102
1103 /**
1104  * Used for specifying the function that should be called when a
1105  * LISTENing connection has been connected to another host.
1106  *
1107  * @param pcb tcp_pcb to set the accept callback
1108  * @param accept callback function to call for this pcb when LISTENing
1109  *        connection has been connected to another host
1110  */ 
1111 void
1112 tcp_accept(struct tcp_pcb *pcb,
1113      err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err))
1114 {
1115   ((struct tcp_pcb_listen *)pcb)->accept = accept;
1116 }
1117 #endif /* LWIP_CALLBACK_API */
1118
1119
1120 /**
1121  * Used to specify the function that should be called periodically
1122  * from TCP. The interval is specified in terms of the TCP coarse
1123  * timer interval, which is called twice a second.
1124  *
1125  */ 
1126 void
1127 tcp_poll(struct tcp_pcb *pcb,
1128    err_t (* poll)(void *arg, struct tcp_pcb *tpcb), u8_t interval)
1129 {
1130 #if LWIP_CALLBACK_API
1131   pcb->poll = poll;
1132 #endif /* LWIP_CALLBACK_API */  
1133   pcb->pollinterval = interval;
1134 }
1135
1136 /**
1137  * Purges a TCP PCB. Removes any buffered data and frees the buffer memory
1138  * (pcb->ooseq, pcb->unsent and pcb->unacked are freed).
1139  *
1140  * @param pcb tcp_pcb to purge. The pcb itself is not deallocated!
1141  */
1142 void
1143 tcp_pcb_purge(struct tcp_pcb *pcb)
1144 {
1145   if (pcb->state != CLOSED &&
1146      pcb->state != TIME_WAIT &&
1147      pcb->state != LISTEN) {
1148
1149     LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge\n"));
1150
1151     if (pcb->refused_data != NULL) {
1152       LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->refused_data\n"));
1153       pbuf_free(pcb->refused_data);
1154       pcb->refused_data = NULL;
1155     }
1156     if (pcb->unsent != NULL) {
1157       LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: not all data sent\n"));
1158     }
1159     if (pcb->unacked != NULL) {
1160       LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->unacked\n"));
1161     }
1162 #if TCP_QUEUE_OOSEQ /* LW */
1163     if (pcb->ooseq != NULL) {
1164       LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n"));
1165     }
1166
1167     /* Stop the retransmission timer as it will expect data on unacked
1168        queue if it fires */
1169     pcb->rtime = -1;
1170
1171     tcp_segs_free(pcb->ooseq);
1172     pcb->ooseq = NULL;
1173 #endif /* TCP_QUEUE_OOSEQ */
1174     tcp_segs_free(pcb->unsent);
1175     tcp_segs_free(pcb->unacked);
1176     pcb->unacked = pcb->unsent = NULL;
1177   }
1178 }
1179
1180 /**
1181  * Purges the PCB and removes it from a PCB list. Any delayed ACKs are sent first.
1182  *
1183  * @param pcblist PCB list to purge.
1184  * @param pcb tcp_pcb to purge. The pcb itself is also deallocated!
1185  */
1186 void
1187 tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb)
1188 {
1189   TCP_RMV(pcblist, pcb);
1190
1191   tcp_pcb_purge(pcb);
1192   
1193   /* if there is an outstanding delayed ACKs, send it */
1194   if (pcb->state != TIME_WAIT &&
1195      pcb->state != LISTEN &&
1196      pcb->flags & TF_ACK_DELAY) {
1197     pcb->flags |= TF_ACK_NOW;
1198     tcp_output(pcb);
1199   }
1200
1201   if (pcb->state != LISTEN) {
1202     LWIP_ASSERT("unsent segments leaking", pcb->unsent == NULL);
1203     LWIP_ASSERT("unacked segments leaking", pcb->unacked == NULL);
1204 #if TCP_QUEUE_OOSEQ
1205     LWIP_ASSERT("ooseq segments leaking", pcb->ooseq == NULL);
1206 #endif /* TCP_QUEUE_OOSEQ */
1207   }
1208
1209   pcb->state = CLOSED;
1210
1211   LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane());
1212 }
1213
1214 /**
1215  * Calculates a new initial sequence number for new connections.
1216  *
1217  * @return u32_t pseudo random sequence number
1218  */
1219 u32_t
1220 tcp_next_iss(void)
1221 {
1222   static u32_t iss = 6510;
1223   
1224   iss += tcp_ticks;       /* XXX */
1225   return iss;
1226 }
1227
1228 #if TCP_CALCULATE_EFF_SEND_MSS
1229 /**
1230  * Calcluates the effective send mss that can be used for a specific IP address
1231  * by using ip_route to determin the netif used to send to the address and
1232  * calculating the minimum of TCP_MSS and that netif's mtu (if set).
1233  */
1234 u16_t
1235 tcp_eff_send_mss(u16_t sendmss, struct ip_addr *addr)
1236 {
1237   u16_t mss_s;
1238   struct netif *outif;
1239
1240   outif = ip_route(addr);
1241   if ((outif != NULL) && (outif->mtu != 0)) {
1242     mss_s = outif->mtu - IP_HLEN - TCP_HLEN;
1243     /* RFC 1122, chap 4.2.2.6:
1244      * Eff.snd.MSS = min(SendMSS+20, MMS_S) - TCPhdrsize - IPoptionsize
1245      * but we only send options with SYN and that is never filled with data! */
1246     sendmss = LWIP_MIN(sendmss, mss_s);
1247   }
1248   return sendmss;
1249 }
1250 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
1251
1252 #if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG
1253 /**
1254  * Print a tcp header for debugging purposes.
1255  *
1256  * @param tcphdr pointer to a struct tcp_hdr
1257  */
1258 void
1259 tcp_debug_print(struct tcp_hdr *tcphdr)
1260 {
1261   LWIP_DEBUGF(TCP_DEBUG, ("TCP header:\n"));
1262   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
1263   LWIP_DEBUGF(TCP_DEBUG, ("|    %5"U16_F"      |    %5"U16_F"      | (src port, dest port)\n",
1264          ntohs(tcphdr->src), ntohs(tcphdr->dest)));
1265   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
1266   LWIP_DEBUGF(TCP_DEBUG, ("|           %010"U32_F"          | (seq no)\n",
1267           ntohl(tcphdr->seqno)));
1268   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
1269   LWIP_DEBUGF(TCP_DEBUG, ("|           %010"U32_F"          | (ack no)\n",
1270          ntohl(tcphdr->ackno)));
1271   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
1272   LWIP_DEBUGF(TCP_DEBUG, ("| %2"U16_F" |   |%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"|     %5"U16_F"     | (hdrlen, flags (",
1273        TCPH_HDRLEN(tcphdr),
1274          TCPH_FLAGS(tcphdr) >> 5 & 1,
1275          TCPH_FLAGS(tcphdr) >> 4 & 1,
1276          TCPH_FLAGS(tcphdr) >> 3 & 1,
1277          TCPH_FLAGS(tcphdr) >> 2 & 1,
1278          TCPH_FLAGS(tcphdr) >> 1 & 1,
1279          TCPH_FLAGS(tcphdr) & 1,
1280          ntohs(tcphdr->wnd)));
1281   tcp_debug_print_flags(TCPH_FLAGS(tcphdr));
1282   LWIP_DEBUGF(TCP_DEBUG, ("), win)\n"));
1283   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
1284   LWIP_DEBUGF(TCP_DEBUG, ("|    0x%04"X16_F"     |     %5"U16_F"     | (chksum, urgp)\n",
1285          ntohs(tcphdr->chksum), ntohs(tcphdr->urgp)));
1286   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
1287 }
1288
1289 /**
1290  * Print a tcp state for debugging purposes.
1291  *
1292  * @param s enum tcp_state to print
1293  */
1294 void
1295 tcp_debug_print_state(enum tcp_state s)
1296 {
1297   LWIP_DEBUGF(TCP_DEBUG, ("State: "));
1298   switch (s) {
1299   case CLOSED:
1300     LWIP_DEBUGF(TCP_DEBUG, ("CLOSED\n"));
1301     break;
1302  case LISTEN:
1303    LWIP_DEBUGF(TCP_DEBUG, ("LISTEN\n"));
1304    break;
1305   case SYN_SENT:
1306     LWIP_DEBUGF(TCP_DEBUG, ("SYN_SENT\n"));
1307     break;
1308   case SYN_RCVD:
1309     LWIP_DEBUGF(TCP_DEBUG, ("SYN_RCVD\n"));
1310     break;
1311   case ESTABLISHED:
1312     LWIP_DEBUGF(TCP_DEBUG, ("ESTABLISHED\n"));
1313     break;
1314   case FIN_WAIT_1:
1315     LWIP_DEBUGF(TCP_DEBUG, ("FIN_WAIT_1\n"));
1316     break;
1317   case FIN_WAIT_2:
1318     LWIP_DEBUGF(TCP_DEBUG, ("FIN_WAIT_2\n"));
1319     break;
1320   case CLOSE_WAIT:
1321     LWIP_DEBUGF(TCP_DEBUG, ("CLOSE_WAIT\n"));
1322     break;
1323   case CLOSING:
1324     LWIP_DEBUGF(TCP_DEBUG, ("CLOSING\n"));
1325     break;
1326   case LAST_ACK:
1327     LWIP_DEBUGF(TCP_DEBUG, ("LAST_ACK\n"));
1328     break;
1329   case TIME_WAIT:
1330     LWIP_DEBUGF(TCP_DEBUG, ("TIME_WAIT\n"));
1331    break;
1332   }
1333 }
1334
1335 /**
1336  * Print tcp flags for debugging purposes.
1337  *
1338  * @param flags tcp flags, all active flags are printed
1339  */
1340 void
1341 tcp_debug_print_flags(u8_t flags)
1342 {
1343   if (flags & TCP_FIN) {
1344     LWIP_DEBUGF(TCP_DEBUG, ("FIN "));
1345   }
1346   if (flags & TCP_SYN) {
1347     LWIP_DEBUGF(TCP_DEBUG, ("SYN "));
1348   }
1349   if (flags & TCP_RST) {
1350     LWIP_DEBUGF(TCP_DEBUG, ("RST "));
1351   }
1352   if (flags & TCP_PSH) {
1353     LWIP_DEBUGF(TCP_DEBUG, ("PSH "));
1354   }
1355   if (flags & TCP_ACK) {
1356     LWIP_DEBUGF(TCP_DEBUG, ("ACK "));
1357   }
1358   if (flags & TCP_URG) {
1359     LWIP_DEBUGF(TCP_DEBUG, ("URG "));
1360   }
1361   if (flags & TCP_ECE) {
1362     LWIP_DEBUGF(TCP_DEBUG, ("ECE "));
1363   }
1364   if (flags & TCP_CWR) {
1365     LWIP_DEBUGF(TCP_DEBUG, ("CWR "));
1366   }
1367 }
1368
1369 /**
1370  * Print all tcp_pcbs in every list for debugging purposes.
1371  */
1372 void
1373 tcp_debug_print_pcbs(void)
1374 {
1375   struct tcp_pcb *pcb;
1376   LWIP_DEBUGF(TCP_DEBUG, ("Active PCB states:\n"));
1377   for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
1378     LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
1379                        pcb->local_port, pcb->remote_port,
1380                        pcb->snd_nxt, pcb->rcv_nxt));
1381     tcp_debug_print_state(pcb->state);
1382   }    
1383   LWIP_DEBUGF(TCP_DEBUG, ("Listen PCB states:\n"));
1384   for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) {
1385     LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
1386                        pcb->local_port, pcb->remote_port,
1387                        pcb->snd_nxt, pcb->rcv_nxt));
1388     tcp_debug_print_state(pcb->state);
1389   }    
1390   LWIP_DEBUGF(TCP_DEBUG, ("TIME-WAIT PCB states:\n"));
1391   for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
1392     LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
1393                        pcb->local_port, pcb->remote_port,
1394                        pcb->snd_nxt, pcb->rcv_nxt));
1395     tcp_debug_print_state(pcb->state);
1396   }    
1397 }
1398
1399 /**
1400  * Check state consistency of the tcp_pcb lists.
1401  */
1402 s16_t
1403 tcp_pcbs_sane(void)
1404 {
1405   struct tcp_pcb *pcb;
1406   for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
1407     LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != CLOSED", pcb->state != CLOSED);
1408     LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != LISTEN", pcb->state != LISTEN);
1409     LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
1410   }
1411   for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
1412     LWIP_ASSERT("tcp_pcbs_sane: tw pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
1413   }
1414   return 1;
1415 }
1416 #endif /* TCP_DEBUG */
1417
1418 #endif /* LWIP_TCP */