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