source: UsbWattMeter/trunk/lwip-1.4.1/src/core/tcp.c@ 164

Last change on this file since 164 was 164, checked in by coas-nagasima, 8 years ago

TOPPERS/ECNLサンプルアプリ「USB充電器電力計」を追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 52.4 KB
Line 
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#include "lwip/tcp_impl.h"
53#include "lwip/debug.h"
54#include "lwip/stats.h"
55
56#include <string.h>
57
58#ifndef TCP_LOCAL_PORT_RANGE_START
59/* From http://www.iana.org/assignments/port-numbers:
60 "The Dynamic and/or Private Ports are those from 49152 through 65535" */
61#define TCP_LOCAL_PORT_RANGE_START 0xc000
62#define TCP_LOCAL_PORT_RANGE_END 0xffff
63#define TCP_ENSURE_LOCAL_PORT_RANGE(port) (((port) & ~TCP_LOCAL_PORT_RANGE_START) + TCP_LOCAL_PORT_RANGE_START)
64#endif
65
66#if LWIP_TCP_KEEPALIVE
67#define TCP_KEEP_DUR(pcb) ((pcb)->keep_cnt * (pcb)->keep_intvl)
68#define TCP_KEEP_INTVL(pcb) ((pcb)->keep_intvl)
69#else /* LWIP_TCP_KEEPALIVE */
70#define TCP_KEEP_DUR(pcb) TCP_MAXIDLE
71#define TCP_KEEP_INTVL(pcb) TCP_KEEPINTVL_DEFAULT
72#endif /* LWIP_TCP_KEEPALIVE */
73
74const char * const tcp_state_str[] = {
75 "CLOSED",
76 "LISTEN",
77 "SYN_SENT",
78 "SYN_RCVD",
79 "ESTABLISHED",
80 "FIN_WAIT_1",
81 "FIN_WAIT_2",
82 "CLOSE_WAIT",
83 "CLOSING",
84 "LAST_ACK",
85 "TIME_WAIT"
86};
87
88/* last local TCP port */
89static u16_t tcp_port = TCP_LOCAL_PORT_RANGE_START;
90
91/* Incremented every coarse grained timer shot (typically every 500 ms). */
92u32_t tcp_ticks;
93const u8_t tcp_backoff[13] =
94 { 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7};
95 /* Times per slowtmr hits */
96const u8_t tcp_persist_backoff[7] = { 3, 6, 12, 24, 48, 96, 120 };
97
98/* The TCP PCB lists. */
99
100/** List of all TCP PCBs bound but not yet (connected || listening) */
101struct tcp_pcb *tcp_bound_pcbs;
102/** List of all TCP PCBs in LISTEN state */
103union tcp_listen_pcbs_t tcp_listen_pcbs;
104/** List of all TCP PCBs that are in a state in which
105 * they accept or send data. */
106struct tcp_pcb *tcp_active_pcbs;
107/** List of all TCP PCBs in TIME-WAIT state */
108struct tcp_pcb *tcp_tw_pcbs;
109
110#define NUM_TCP_PCB_LISTS 4
111#define NUM_TCP_PCB_LISTS_NO_TIME_WAIT 3
112/** An array with all (non-temporary) PCB lists, mainly used for smaller code size */
113struct tcp_pcb ** const tcp_pcb_lists[] = {&tcp_listen_pcbs.pcbs, &tcp_bound_pcbs,
114 &tcp_active_pcbs, &tcp_tw_pcbs};
115
116/** Only used for temporary storage. */
117struct tcp_pcb *tcp_tmp_pcb;
118
119u8_t tcp_active_pcbs_changed;
120
121/** Timer counter to handle calling slow-timer from tcp_tmr() */
122static u8_t tcp_timer;
123static u8_t tcp_timer_ctr;
124static u16_t tcp_new_port(void);
125
126/**
127 * Initialize this module.
128 */
129void
130tcp_init(void)
131{
132#if LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND)
133 tcp_port = TCP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND());
134#endif /* LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) */
135}
136
137/**
138 * Called periodically to dispatch TCP timers.
139 */
140void
141tcp_tmr(void)
142{
143 /* Call tcp_fasttmr() every 250 ms */
144 tcp_fasttmr();
145
146 if (++tcp_timer & 1) {
147 /* Call tcp_tmr() every 500 ms, i.e., every other timer
148 tcp_tmr() is called. */
149 tcp_slowtmr();
150 }
151}
152
153/**
154 * Closes the TX side of a connection held by the PCB.
155 * For tcp_close(), a RST is sent if the application didn't receive all data
156 * (tcp_recved() not called for all data passed to recv callback).
157 *
158 * Listening pcbs are freed and may not be referenced any more.
159 * Connection pcbs are freed if not yet connected and may not be referenced
160 * any more. If a connection is established (at least SYN received or in
161 * a closing state), the connection is closed, and put in a closing state.
162 * The pcb is then automatically freed in tcp_slowtmr(). It is therefore
163 * unsafe to reference it.
164 *
165 * @param pcb the tcp_pcb to close
166 * @return ERR_OK if connection has been closed
167 * another err_t if closing failed and pcb is not freed
168 */
169static err_t
170tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data)
171{
172 err_t err;
173
174 if (rst_on_unacked_data && ((pcb->state == ESTABLISHED) || (pcb->state == CLOSE_WAIT))) {
175 if ((pcb->refused_data != NULL) || (pcb->rcv_wnd != TCP_WND)) {
176 /* Not all data received by application, send RST to tell the remote
177 side about this. */
178 LWIP_ASSERT("pcb->flags & TF_RXCLOSED", pcb->flags & TF_RXCLOSED);
179
180 /* don't call tcp_abort here: we must not deallocate the pcb since
181 that might not be expected when calling tcp_close */
182 tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip,
183 pcb->local_port, pcb->remote_port);
184
185 tcp_pcb_purge(pcb);
186 TCP_RMV_ACTIVE(pcb);
187 if (pcb->state == ESTABLISHED) {
188 /* move to TIME_WAIT since we close actively */
189 pcb->state = TIME_WAIT;
190 TCP_REG(&tcp_tw_pcbs, pcb);
191 } else {
192 /* CLOSE_WAIT: deallocate the pcb since we already sent a RST for it */
193 memp_free(MEMP_TCP_PCB, pcb);
194 }
195 return ERR_OK;
196 }
197 }
198
199 switch (pcb->state) {
200 case CLOSED:
201 /* Closing a pcb in the CLOSED state might seem erroneous,
202 * however, it is in this state once allocated and as yet unused
203 * and the user needs some way to free it should the need arise.
204 * Calling tcp_close() with a pcb that has already been closed, (i.e. twice)
205 * or for a pcb that has been used and then entered the CLOSED state
206 * is erroneous, but this should never happen as the pcb has in those cases
207 * been freed, and so any remaining handles are bogus. */
208 err = ERR_OK;
209 if (pcb->local_port != 0) {
210 TCP_RMV(&tcp_bound_pcbs, pcb);
211 }
212 memp_free(MEMP_TCP_PCB, pcb);
213 pcb = NULL;
214 break;
215 case LISTEN:
216 err = ERR_OK;
217 tcp_pcb_remove(&tcp_listen_pcbs.pcbs, pcb);
218 memp_free(MEMP_TCP_PCB_LISTEN, pcb);
219 pcb = NULL;
220 break;
221 case SYN_SENT:
222 err = ERR_OK;
223 TCP_PCB_REMOVE_ACTIVE(pcb);
224 memp_free(MEMP_TCP_PCB, pcb);
225 pcb = NULL;
226 snmp_inc_tcpattemptfails();
227 break;
228 case SYN_RCVD:
229 err = tcp_send_fin(pcb);
230 if (err == ERR_OK) {
231 snmp_inc_tcpattemptfails();
232 pcb->state = FIN_WAIT_1;
233 }
234 break;
235 case ESTABLISHED:
236 err = tcp_send_fin(pcb);
237 if (err == ERR_OK) {
238 snmp_inc_tcpestabresets();
239 pcb->state = FIN_WAIT_1;
240 }
241 break;
242 case CLOSE_WAIT:
243 err = tcp_send_fin(pcb);
244 if (err == ERR_OK) {
245 snmp_inc_tcpestabresets();
246 pcb->state = LAST_ACK;
247 }
248 break;
249 default:
250 /* Has already been closed, do nothing. */
251 err = ERR_OK;
252 pcb = NULL;
253 break;
254 }
255
256 if (pcb != NULL && err == ERR_OK) {
257 /* To ensure all data has been sent when tcp_close returns, we have
258 to make sure tcp_output doesn't fail.
259 Since we don't really have to ensure all data has been sent when tcp_close
260 returns (unsent data is sent from tcp timer functions, also), we don't care
261 for the return value of tcp_output for now. */
262 /* @todo: When implementing SO_LINGER, this must be changed somehow:
263 If SOF_LINGER is set, the data should be sent and acked before close returns.
264 This can only be valid for sequential APIs, not for the raw API. */
265 tcp_output(pcb);
266 }
267 return err;
268}
269
270/**
271 * Closes the connection held by the PCB.
272 *
273 * Listening pcbs are freed and may not be referenced any more.
274 * Connection pcbs are freed if not yet connected and may not be referenced
275 * any more. If a connection is established (at least SYN received or in
276 * a closing state), the connection is closed, and put in a closing state.
277 * The pcb is then automatically freed in tcp_slowtmr(). It is therefore
278 * unsafe to reference it (unless an error is returned).
279 *
280 * @param pcb the tcp_pcb to close
281 * @return ERR_OK if connection has been closed
282 * another err_t if closing failed and pcb is not freed
283 */
284err_t
285tcp_close(struct tcp_pcb *pcb)
286{
287#if TCP_DEBUG
288 LWIP_DEBUGF(TCP_DEBUG, ("tcp_close: closing in "));
289 tcp_debug_print_state(pcb->state);
290#endif /* TCP_DEBUG */
291
292 if (pcb->state != LISTEN) {
293 /* Set a flag not to receive any more data... */
294 pcb->flags |= TF_RXCLOSED;
295 }
296 /* ... and close */
297 return tcp_close_shutdown(pcb, 1);
298}
299
300/**
301 * Causes all or part of a full-duplex connection of this PCB to be shut down.
302 * This doesn't deallocate the PCB unless shutting down both sides!
303 * Shutting down both sides is the same as calling tcp_close, so if it succeds,
304 * the PCB should not be referenced any more.
305 *
306 * @param pcb PCB to shutdown
307 * @param shut_rx shut down receive side if this is != 0
308 * @param shut_tx shut down send side if this is != 0
309 * @return ERR_OK if shutdown succeeded (or the PCB has already been shut down)
310 * another err_t on error.
311 */
312err_t
313tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx)
314{
315 if (pcb->state == LISTEN) {
316 return ERR_CONN;
317 }
318 if (shut_rx) {
319 /* shut down the receive side: set a flag not to receive any more data... */
320 pcb->flags |= TF_RXCLOSED;
321 if (shut_tx) {
322 /* shutting down the tx AND rx side is the same as closing for the raw API */
323 return tcp_close_shutdown(pcb, 1);
324 }
325 /* ... and free buffered data */
326 if (pcb->refused_data != NULL) {
327 pbuf_free(pcb->refused_data);
328 pcb->refused_data = NULL;
329 }
330 }
331 if (shut_tx) {
332 /* This can't happen twice since if it succeeds, the pcb's state is changed.
333 Only close in these states as the others directly deallocate the PCB */
334 switch (pcb->state) {
335 case SYN_RCVD:
336 case ESTABLISHED:
337 case CLOSE_WAIT:
338 return tcp_close_shutdown(pcb, shut_rx);
339 default:
340 /* Not (yet?) connected, cannot shutdown the TX side as that would bring us
341 into CLOSED state, where the PCB is deallocated. */
342 return ERR_CONN;
343 }
344 }
345 return ERR_OK;
346}
347
348/**
349 * Abandons a connection and optionally sends a RST to the remote
350 * host. Deletes the local protocol control block. This is done when
351 * a connection is killed because of shortage of memory.
352 *
353 * @param pcb the tcp_pcb to abort
354 * @param reset boolean to indicate whether a reset should be sent
355 */
356void
357tcp_abandon(struct tcp_pcb *pcb, int reset)
358{
359 u32_t seqno, ackno;
360#if LWIP_CALLBACK_API
361 tcp_err_fn errf;
362#endif /* LWIP_CALLBACK_API */
363 void *errf_arg;
364
365 /* pcb->state LISTEN not allowed here */
366 LWIP_ASSERT("don't call tcp_abort/tcp_abandon for listen-pcbs",
367 pcb->state != LISTEN);
368 /* Figure out on which TCP PCB list we are, and remove us. If we
369 are in an active state, call the receive function associated with
370 the PCB with a NULL argument, and send an RST to the remote end. */
371 if (pcb->state == TIME_WAIT) {
372 tcp_pcb_remove(&tcp_tw_pcbs, pcb);
373 memp_free(MEMP_TCP_PCB, pcb);
374 } else {
375 seqno = pcb->snd_nxt;
376 ackno = pcb->rcv_nxt;
377#if LWIP_CALLBACK_API
378 errf = pcb->errf;
379#endif /* LWIP_CALLBACK_API */
380 errf_arg = pcb->callback_arg;
381 TCP_PCB_REMOVE_ACTIVE(pcb);
382 if (pcb->unacked != NULL) {
383 tcp_segs_free(pcb->unacked);
384 }
385 if (pcb->unsent != NULL) {
386 tcp_segs_free(pcb->unsent);
387 }
388#if TCP_QUEUE_OOSEQ
389 if (pcb->ooseq != NULL) {
390 tcp_segs_free(pcb->ooseq);
391 }
392#endif /* TCP_QUEUE_OOSEQ */
393 if (reset) {
394 LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abandon: sending RST\n"));
395 tcp_rst(seqno, ackno, &pcb->local_ip, &pcb->remote_ip, pcb->local_port, pcb->remote_port);
396 }
397 memp_free(MEMP_TCP_PCB, pcb);
398 TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT);
399 }
400}
401
402/**
403 * Aborts the connection by sending a RST (reset) segment to the remote
404 * host. The pcb is deallocated. This function never fails.
405 *
406 * ATTENTION: When calling this from one of the TCP callbacks, make
407 * sure you always return ERR_ABRT (and never return ERR_ABRT otherwise
408 * or you will risk accessing deallocated memory or memory leaks!
409 *
410 * @param pcb the tcp pcb to abort
411 */
412void
413tcp_abort(struct tcp_pcb *pcb)
414{
415 tcp_abandon(pcb, 1);
416}
417
418/**
419 * Binds the connection to a local portnumber and IP address. If the
420 * IP address is not given (i.e., ipaddr == NULL), the IP address of
421 * the outgoing network interface is used instead.
422 *
423 * @param pcb the tcp_pcb to bind (no check is done whether this pcb is
424 * already bound!)
425 * @param ipaddr the local ip address to bind to (use IP_ADDR_ANY to bind
426 * to any local address
427 * @param port the local port to bind to
428 * @return ERR_USE if the port is already in use
429 * ERR_VAL if bind failed because the PCB is not in a valid state
430 * ERR_OK if bound
431 */
432err_t
433tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port)
434{
435 int i;
436 int max_pcb_list = NUM_TCP_PCB_LISTS;
437 struct tcp_pcb *cpcb;
438
439 LWIP_ERROR("tcp_bind: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_VAL);
440
441#if SO_REUSE
442 /* Unless the REUSEADDR flag is set,
443 we have to check the pcbs in TIME-WAIT state, also.
444 We do not dump TIME_WAIT pcb's; they can still be matched by incoming
445 packets using both local and remote IP addresses and ports to distinguish.
446 */
447 if (ip_get_option(pcb, SOF_REUSEADDR)) {
448 max_pcb_list = NUM_TCP_PCB_LISTS_NO_TIME_WAIT;
449 }
450#endif /* SO_REUSE */
451
452 if (port == 0) {
453 port = tcp_new_port();
454 if (port == 0) {
455 return ERR_BUF;
456 }
457 }
458
459 /* Check if the address already is in use (on all lists) */
460 for (i = 0; i < max_pcb_list; i++) {
461 for(cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) {
462 if (cpcb->local_port == port) {
463#if SO_REUSE
464 /* Omit checking for the same port if both pcbs have REUSEADDR set.
465 For SO_REUSEADDR, the duplicate-check for a 5-tuple is done in
466 tcp_connect. */
467 if (!ip_get_option(pcb, SOF_REUSEADDR) ||
468 !ip_get_option(cpcb, SOF_REUSEADDR))
469#endif /* SO_REUSE */
470 {
471 if (ip_addr_isany(&(cpcb->local_ip)) ||
472 ip_addr_isany(ipaddr) ||
473 ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {
474 return ERR_USE;
475 }
476 }
477 }
478 }
479 }
480
481 if (!ip_addr_isany(ipaddr)) {
482 pcb->local_ip = *ipaddr;
483 }
484 pcb->local_port = port;
485 TCP_REG(&tcp_bound_pcbs, pcb);
486 LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %"U16_F"\n", port));
487 return ERR_OK;
488}
489#if LWIP_CALLBACK_API
490/**
491 * Default accept callback if no accept callback is specified by the user.
492 */
493static err_t
494tcp_accept_null(void *arg, struct tcp_pcb *pcb, err_t err)
495{
496 LWIP_UNUSED_ARG(arg);
497 LWIP_UNUSED_ARG(pcb);
498 LWIP_UNUSED_ARG(err);
499
500 return ERR_ABRT;
501}
502#endif /* LWIP_CALLBACK_API */
503
504/**
505 * Set the state of the connection to be LISTEN, which means that it
506 * is able to accept incoming connections. The protocol control block
507 * is reallocated in order to consume less memory. Setting the
508 * connection to LISTEN is an irreversible process.
509 *
510 * @param pcb the original tcp_pcb
511 * @param backlog the incoming connections queue limit
512 * @return tcp_pcb used for listening, consumes less memory.
513 *
514 * @note The original tcp_pcb is freed. This function therefore has to be
515 * called like this:
516 * tpcb = tcp_listen(tpcb);
517 */
518struct tcp_pcb *
519tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
520{
521 struct tcp_pcb_listen *lpcb;
522
523 LWIP_UNUSED_ARG(backlog);
524 LWIP_ERROR("tcp_listen: pcb already connected", pcb->state == CLOSED, return NULL);
525
526 /* already listening? */
527 if (pcb->state == LISTEN) {
528 return pcb;
529 }
530#if SO_REUSE
531 if (ip_get_option(pcb, SOF_REUSEADDR)) {
532 /* Since SOF_REUSEADDR allows reusing a local address before the pcb's usage
533 is declared (listen-/connection-pcb), we have to make sure now that
534 this port is only used once for every local IP. */
535 for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
536 if (lpcb->local_port == pcb->local_port) {
537 if (ip_addr_cmp(&lpcb->local_ip, &pcb->local_ip)) {
538 /* this address/port is already used */
539 return NULL;
540 }
541 }
542 }
543 }
544#endif /* SO_REUSE */
545 lpcb = (struct tcp_pcb_listen *)memp_malloc(MEMP_TCP_PCB_LISTEN);
546 if (lpcb == NULL) {
547 return NULL;
548 }
549 lpcb->callback_arg = pcb->callback_arg;
550 lpcb->local_port = pcb->local_port;
551 lpcb->state = LISTEN;
552 lpcb->prio = pcb->prio;
553 lpcb->so_options = pcb->so_options;
554 ip_set_option(lpcb, SOF_ACCEPTCONN);
555 lpcb->ttl = pcb->ttl;
556 lpcb->tos = pcb->tos;
557 ip_addr_copy(lpcb->local_ip, pcb->local_ip);
558 if (pcb->local_port != 0) {
559 TCP_RMV(&tcp_bound_pcbs, pcb);
560 }
561 memp_free(MEMP_TCP_PCB, pcb);
562#if LWIP_CALLBACK_API
563 lpcb->accept = tcp_accept_null;
564#endif /* LWIP_CALLBACK_API */
565#if TCP_LISTEN_BACKLOG
566 lpcb->accepts_pending = 0;
567 lpcb->backlog = (backlog ? backlog : 1);
568#endif /* TCP_LISTEN_BACKLOG */
569 TCP_REG(&tcp_listen_pcbs.pcbs, (struct tcp_pcb *)lpcb);
570 return (struct tcp_pcb *)lpcb;
571}
572
573/**
574 * Update the state that tracks the available window space to advertise.
575 *
576 * Returns how much extra window would be advertised if we sent an
577 * update now.
578 */
579u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb)
580{
581 u32_t new_right_edge = pcb->rcv_nxt + pcb->rcv_wnd;
582
583 if (TCP_SEQ_GEQ(new_right_edge, pcb->rcv_ann_right_edge + LWIP_MIN((TCP_WND / 2), pcb->mss))) {
584 /* we can advertise more window */
585 pcb->rcv_ann_wnd = pcb->rcv_wnd;
586 return new_right_edge - pcb->rcv_ann_right_edge;
587 } else {
588 if (TCP_SEQ_GT(pcb->rcv_nxt, pcb->rcv_ann_right_edge)) {
589 /* Can happen due to other end sending out of advertised window,
590 * but within actual available (but not yet advertised) window */
591 pcb->rcv_ann_wnd = 0;
592 } else {
593 /* keep the right edge of window constant */
594 u32_t new_rcv_ann_wnd = pcb->rcv_ann_right_edge - pcb->rcv_nxt;
595 LWIP_ASSERT("new_rcv_ann_wnd <= 0xffff", new_rcv_ann_wnd <= 0xffff);
596 pcb->rcv_ann_wnd = (u16_t)new_rcv_ann_wnd;
597 }
598 return 0;
599 }
600}
601
602/**
603 * This function should be called by the application when it has
604 * processed the data. The purpose is to advertise a larger window
605 * when the data has been processed.
606 *
607 * @param pcb the tcp_pcb for which data is read
608 * @param len the amount of bytes that have been read by the application
609 */
610void
611tcp_recved(struct tcp_pcb *pcb, u16_t len)
612{
613 int wnd_inflation;
614
615 /* pcb->state LISTEN not allowed here */
616 LWIP_ASSERT("don't call tcp_recved for listen-pcbs",
617 pcb->state != LISTEN);
618 LWIP_ASSERT("tcp_recved: len would wrap rcv_wnd\n",
619 len <= 0xffff - pcb->rcv_wnd );
620
621 pcb->rcv_wnd += len;
622 if (pcb->rcv_wnd > TCP_WND) {
623 pcb->rcv_wnd = TCP_WND;
624 }
625
626 wnd_inflation = tcp_update_rcv_ann_wnd(pcb);
627
628 /* If the change in the right edge of window is significant (default
629 * watermark is TCP_WND/4), then send an explicit update now.
630 * Otherwise wait for a packet to be sent in the normal course of
631 * events (or more window to be available later) */
632 if (wnd_inflation >= TCP_WND_UPDATE_THRESHOLD) {
633 tcp_ack_now(pcb);
634 tcp_output(pcb);
635 }
636
637 LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: recveived %"U16_F" bytes, wnd %"U16_F" (%"U16_F").\n",
638 len, pcb->rcv_wnd, TCP_WND - pcb->rcv_wnd));
639}
640
641/**
642 * Allocate a new local TCP port.
643 *
644 * @return a new (free) local TCP port number
645 */
646static u16_t
647tcp_new_port(void)
648{
649 u8_t i;
650 u16_t n = 0;
651 struct tcp_pcb *pcb;
652
653again:
654 if (tcp_port++ == TCP_LOCAL_PORT_RANGE_END) {
655 tcp_port = TCP_LOCAL_PORT_RANGE_START;
656 }
657 /* Check all PCB lists. */
658 for (i = 0; i < NUM_TCP_PCB_LISTS; i++) {
659 for(pcb = *tcp_pcb_lists[i]; pcb != NULL; pcb = pcb->next) {
660 if (pcb->local_port == tcp_port) {
661 if (++n > (TCP_LOCAL_PORT_RANGE_END - TCP_LOCAL_PORT_RANGE_START)) {
662 return 0;
663 }
664 goto again;
665 }
666 }
667 }
668 return tcp_port;
669}
670
671/**
672 * Connects to another host. The function given as the "connected"
673 * argument will be called when the connection has been established.
674 *
675 * @param pcb the tcp_pcb used to establish the connection
676 * @param ipaddr the remote ip address to connect to
677 * @param port the remote tcp port to connect to
678 * @param connected callback function to call when connected (or on error)
679 * @return ERR_VAL if invalid arguments are given
680 * ERR_OK if connect request has been sent
681 * other err_t values if connect request couldn't be sent
682 */
683err_t
684tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port,
685 tcp_connected_fn connected)
686{
687 err_t ret;
688 u32_t iss;
689 u16_t old_local_port;
690
691 LWIP_ERROR("tcp_connect: can only connect from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN);
692
693 LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port));
694 if (ipaddr != NULL) {
695 pcb->remote_ip = *ipaddr;
696 } else {
697 return ERR_VAL;
698 }
699 pcb->remote_port = port;
700
701 /* check if we have a route to the remote host */
702 if (ip_addr_isany(&(pcb->local_ip))) {
703 /* no local IP address set, yet. */
704 struct netif *netif = ip_route(&(pcb->remote_ip));
705 if (netif == NULL) {
706 /* Don't even try to send a SYN packet if we have no route
707 since that will fail. */
708 return ERR_RTE;
709 }
710 /* Use the netif's IP address as local address. */
711 ip_addr_copy(pcb->local_ip, netif->ip_addr);
712 }
713
714 old_local_port = pcb->local_port;
715 if (pcb->local_port == 0) {
716 pcb->local_port = tcp_new_port();
717 if (pcb->local_port == 0) {
718 return ERR_BUF;
719 }
720 }
721#if SO_REUSE
722 if (ip_get_option(pcb, SOF_REUSEADDR)) {
723 /* Since SOF_REUSEADDR allows reusing a local address, we have to make sure
724 now that the 5-tuple is unique. */
725 struct tcp_pcb *cpcb;
726 int i;
727 /* Don't check listen- and bound-PCBs, check active- and TIME-WAIT PCBs. */
728 for (i = 2; i < NUM_TCP_PCB_LISTS; i++) {
729 for(cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) {
730 if ((cpcb->local_port == pcb->local_port) &&
731 (cpcb->remote_port == port) &&
732 ip_addr_cmp(&cpcb->local_ip, &pcb->local_ip) &&
733 ip_addr_cmp(&cpcb->remote_ip, ipaddr)) {
734 /* linux returns EISCONN here, but ERR_USE should be OK for us */
735 return ERR_USE;
736 }
737 }
738 }
739 }
740#endif /* SO_REUSE */
741 iss = tcp_next_iss();
742 pcb->rcv_nxt = 0;
743 pcb->snd_nxt = iss;
744 pcb->lastack = iss - 1;
745 pcb->snd_lbb = iss - 1;
746 pcb->rcv_wnd = TCP_WND;
747 pcb->rcv_ann_wnd = TCP_WND;
748 pcb->rcv_ann_right_edge = pcb->rcv_nxt;
749 pcb->snd_wnd = TCP_WND;
750 /* As initial send MSS, we use TCP_MSS but limit it to 536.
751 The send MSS is updated when an MSS option is received. */
752 pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS;
753#if TCP_CALCULATE_EFF_SEND_MSS
754 pcb->mss = tcp_eff_send_mss(pcb->mss, ipaddr);
755#endif /* TCP_CALCULATE_EFF_SEND_MSS */
756 pcb->cwnd = 1;
757 pcb->ssthresh = pcb->mss * 10;
758#if LWIP_CALLBACK_API
759 pcb->connected = connected;
760#else /* LWIP_CALLBACK_API */
761 LWIP_UNUSED_ARG(connected);
762#endif /* LWIP_CALLBACK_API */
763
764 /* Send a SYN together with the MSS option. */
765 ret = tcp_enqueue_flags(pcb, TCP_SYN);
766 if (ret == ERR_OK) {
767 /* SYN segment was enqueued, changed the pcbs state now */
768 pcb->state = SYN_SENT;
769 if (old_local_port != 0) {
770 TCP_RMV(&tcp_bound_pcbs, pcb);
771 }
772 TCP_REG_ACTIVE(pcb);
773 snmp_inc_tcpactiveopens();
774
775 tcp_output(pcb);
776 }
777 return ret;
778}
779
780/**
781 * Called every 500 ms and implements the retransmission timer and the timer that
782 * removes PCBs that have been in TIME-WAIT for enough time. It also increments
783 * various timers such as the inactivity timer in each PCB.
784 *
785 * Automatically called from tcp_tmr().
786 */
787void
788tcp_slowtmr(void)
789{
790 struct tcp_pcb *pcb, *prev;
791 u16_t eff_wnd;
792 u8_t pcb_remove; /* flag if a PCB should be removed */
793 u8_t pcb_reset; /* flag if a RST should be sent when removing */
794 err_t err;
795
796 err = ERR_OK;
797
798 ++tcp_ticks;
799 ++tcp_timer_ctr;
800
801tcp_slowtmr_start:
802 /* Steps through all of the active PCBs. */
803 prev = NULL;
804 pcb = tcp_active_pcbs;
805 if (pcb == NULL) {
806 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n"));
807 }
808 while (pcb != NULL) {
809 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb\n"));
810 LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED);
811 LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN);
812 LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT);
813 if (pcb->last_timer == tcp_timer_ctr) {
814 /* skip this pcb, we have already processed it */
815 pcb = pcb->next;
816 continue;
817 }
818 pcb->last_timer = tcp_timer_ctr;
819
820 pcb_remove = 0;
821 pcb_reset = 0;
822
823 if (pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) {
824 ++pcb_remove;
825 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n"));
826 }
827 else if (pcb->nrtx == TCP_MAXRTX) {
828 ++pcb_remove;
829 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n"));
830 } else {
831 if (pcb->persist_backoff > 0) {
832 /* If snd_wnd is zero, use persist timer to send 1 byte probes
833 * instead of using the standard retransmission mechanism. */
834 pcb->persist_cnt++;
835 if (pcb->persist_cnt >= tcp_persist_backoff[pcb->persist_backoff-1]) {
836 pcb->persist_cnt = 0;
837 if (pcb->persist_backoff < sizeof(tcp_persist_backoff)) {
838 pcb->persist_backoff++;
839 }
840 tcp_zero_window_probe(pcb);
841 }
842 } else {
843 /* Increase the retransmission timer if it is running */
844 if(pcb->rtime >= 0) {
845 ++pcb->rtime;
846 }
847
848 if (pcb->unacked != NULL && pcb->rtime >= pcb->rto) {
849 /* Time for a retransmission. */
850 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %"S16_F
851 " pcb->rto %"S16_F"\n",
852 pcb->rtime, pcb->rto));
853
854 /* Double retransmission time-out unless we are trying to
855 * connect to somebody (i.e., we are in SYN_SENT). */
856 if (pcb->state != SYN_SENT) {
857 pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx];
858 }
859
860 /* Reset the retransmission timer. */
861 pcb->rtime = 0;
862
863 /* Reduce congestion window and ssthresh. */
864 eff_wnd = LWIP_MIN(pcb->cwnd, pcb->snd_wnd);
865 pcb->ssthresh = eff_wnd >> 1;
866 if (pcb->ssthresh < (pcb->mss << 1)) {
867 pcb->ssthresh = (pcb->mss << 1);
868 }
869 pcb->cwnd = pcb->mss;
870 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: cwnd %"U16_F
871 " ssthresh %"U16_F"\n",
872 pcb->cwnd, pcb->ssthresh));
873
874 /* The following needs to be called AFTER cwnd is set to one
875 mss - STJ */
876 tcp_rexmit_rto(pcb);
877 }
878 }
879 }
880 /* Check if this PCB has stayed too long in FIN-WAIT-2 */
881 if (pcb->state == FIN_WAIT_2) {
882 /* If this PCB is in FIN_WAIT_2 because of SHUT_WR don't let it time out. */
883 if (pcb->flags & TF_RXCLOSED) {
884 /* PCB was fully closed (either through close() or SHUT_RDWR):
885 normal FIN-WAIT timeout handling. */
886 if ((u32_t)(tcp_ticks - pcb->tmr) >
887 TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) {
888 ++pcb_remove;
889 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n"));
890 }
891 }
892 }
893
894 /* Check if KEEPALIVE should be sent */
895 if(ip_get_option(pcb, SOF_KEEPALIVE) &&
896 ((pcb->state == ESTABLISHED) ||
897 (pcb->state == CLOSE_WAIT))) {
898 if((u32_t)(tcp_ticks - pcb->tmr) >
899 (pcb->keep_idle + TCP_KEEP_DUR(pcb)) / TCP_SLOW_INTERVAL)
900 {
901 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to %"U16_F".%"U16_F".%"U16_F".%"U16_F".\n",
902 ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip),
903 ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip)));
904
905 ++pcb_remove;
906 ++pcb_reset;
907 }
908 else if((u32_t)(tcp_ticks - pcb->tmr) >
909 (pcb->keep_idle + pcb->keep_cnt_sent * TCP_KEEP_INTVL(pcb))
910 / TCP_SLOW_INTERVAL)
911 {
912 tcp_keepalive(pcb);
913 pcb->keep_cnt_sent++;
914 }
915 }
916
917 /* If this PCB has queued out of sequence data, but has been
918 inactive for too long, will drop the data (it will eventually
919 be retransmitted). */
920#if TCP_QUEUE_OOSEQ
921 if (pcb->ooseq != NULL &&
922 (u32_t)tcp_ticks - pcb->tmr >= pcb->rto * TCP_OOSEQ_TIMEOUT) {
923 tcp_segs_free(pcb->ooseq);
924 pcb->ooseq = NULL;
925 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: dropping OOSEQ queued data\n"));
926 }
927#endif /* TCP_QUEUE_OOSEQ */
928
929 /* Check if this PCB has stayed too long in SYN-RCVD */
930 if (pcb->state == SYN_RCVD) {
931 if ((u32_t)(tcp_ticks - pcb->tmr) >
932 TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) {
933 ++pcb_remove;
934 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n"));
935 }
936 }
937
938 /* Check if this PCB has stayed too long in LAST-ACK */
939 if (pcb->state == LAST_ACK) {
940 if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {
941 ++pcb_remove;
942 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in LAST-ACK\n"));
943 }
944 }
945
946 /* If the PCB should be removed, do it. */
947 if (pcb_remove) {
948 struct tcp_pcb *pcb2;
949 tcp_err_fn err_fn;
950 void *err_arg;
951 tcp_pcb_purge(pcb);
952 /* Remove PCB from tcp_active_pcbs list. */
953 if (prev != NULL) {
954 LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs);
955 prev->next = pcb->next;
956 } else {
957 /* This PCB was the first. */
958 LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb);
959 tcp_active_pcbs = pcb->next;
960 }
961
962 if (pcb_reset) {
963 tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip,
964 pcb->local_port, pcb->remote_port);
965 }
966
967 err_fn = pcb->errf;
968 err_arg = pcb->callback_arg;
969 pcb2 = pcb;
970 pcb = pcb->next;
971 memp_free(MEMP_TCP_PCB, pcb2);
972
973 tcp_active_pcbs_changed = 0;
974 TCP_EVENT_ERR(err_fn, err_arg, ERR_ABRT);
975 if (tcp_active_pcbs_changed) {
976 goto tcp_slowtmr_start;
977 }
978 } else {
979 /* get the 'next' element now and work with 'prev' below (in case of abort) */
980 prev = pcb;
981 pcb = pcb->next;
982
983 /* We check if we should poll the connection. */
984 ++prev->polltmr;
985 if (prev->polltmr >= prev->pollinterval) {
986 prev->polltmr = 0;
987 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n"));
988 tcp_active_pcbs_changed = 0;
989 TCP_EVENT_POLL(prev, err);
990 if (tcp_active_pcbs_changed) {
991 goto tcp_slowtmr_start;
992 }
993 /* if err == ERR_ABRT, 'prev' is already deallocated */
994 if (err == ERR_OK) {
995 tcp_output(prev);
996 }
997 }
998 }
999 }
1000
1001
1002 /* Steps through all of the TIME-WAIT PCBs. */
1003 prev = NULL;
1004 pcb = tcp_tw_pcbs;
1005 while (pcb != NULL) {
1006 LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
1007 pcb_remove = 0;
1008
1009 /* Check if this PCB has stayed long enough in TIME-WAIT */
1010 if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {
1011 ++pcb_remove;
1012 }
1013
1014
1015
1016 /* If the PCB should be removed, do it. */
1017 if (pcb_remove) {
1018 struct tcp_pcb *pcb2;
1019 tcp_pcb_purge(pcb);
1020 /* Remove PCB from tcp_tw_pcbs list. */
1021 if (prev != NULL) {
1022 LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs);
1023 prev->next = pcb->next;
1024 } else {
1025 /* This PCB was the first. */
1026 LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb);
1027 tcp_tw_pcbs = pcb->next;
1028 }
1029 pcb2 = pcb;
1030 pcb = pcb->next;
1031 memp_free(MEMP_TCP_PCB, pcb2);
1032 } else {
1033 prev = pcb;
1034 pcb = pcb->next;
1035 }
1036 }
1037}
1038
1039/**
1040 * Is called every TCP_FAST_INTERVAL (250 ms) and process data previously
1041 * "refused" by upper layer (application) and sends delayed ACKs.
1042 *
1043 * Automatically called from tcp_tmr().
1044 */
1045void
1046tcp_fasttmr(void)
1047{
1048 struct tcp_pcb *pcb;
1049
1050 ++tcp_timer_ctr;
1051
1052tcp_fasttmr_start:
1053 pcb = tcp_active_pcbs;
1054
1055 while(pcb != NULL) {
1056 if (pcb->last_timer != tcp_timer_ctr) {
1057 struct tcp_pcb *next;
1058 pcb->last_timer = tcp_timer_ctr;
1059 /* send delayed ACKs */
1060 if (pcb->flags & TF_ACK_DELAY) {
1061 LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n"));
1062 tcp_ack_now(pcb);
1063 tcp_output(pcb);
1064 pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
1065 }
1066
1067 next = pcb->next;
1068
1069 /* If there is data which was previously "refused" by upper layer */
1070 if (pcb->refused_data != NULL) {
1071 tcp_active_pcbs_changed = 0;
1072 tcp_process_refused_data(pcb);
1073 if (tcp_active_pcbs_changed) {
1074 /* application callback has changed the pcb list: restart the loop */
1075 goto tcp_fasttmr_start;
1076 }
1077 }
1078 pcb = next;
1079 }
1080 }
1081}
1082
1083/** Pass pcb->refused_data to the recv callback */
1084err_t
1085tcp_process_refused_data(struct tcp_pcb *pcb)
1086{
1087 err_t err;
1088 u8_t refused_flags = pcb->refused_data->flags;
1089 /* set pcb->refused_data to NULL in case the callback frees it and then
1090 closes the pcb */
1091 struct pbuf *refused_data = pcb->refused_data;
1092 pcb->refused_data = NULL;
1093 /* Notify again application with data previously received. */
1094 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: notify kept packet\n"));
1095 TCP_EVENT_RECV(pcb, refused_data, ERR_OK, err);
1096 if (err == ERR_OK) {
1097 /* did refused_data include a FIN? */
1098 if (refused_flags & PBUF_FLAG_TCP_FIN) {
1099 /* correct rcv_wnd as the application won't call tcp_recved()
1100 for the FIN's seqno */
1101 if (pcb->rcv_wnd != TCP_WND) {
1102 pcb->rcv_wnd++;
1103 }
1104 TCP_EVENT_CLOSED(pcb, err);
1105 if (err == ERR_ABRT) {
1106 return ERR_ABRT;
1107 }
1108 }
1109 } else if (err == ERR_ABRT) {
1110 /* if err == ERR_ABRT, 'pcb' is already deallocated */
1111 /* Drop incoming packets because pcb is "full" (only if the incoming
1112 segment contains data). */
1113 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n"));
1114 return ERR_ABRT;
1115 } else {
1116 /* data is still refused, pbuf is still valid (go on for ACK-only packets) */
1117 pcb->refused_data = refused_data;
1118 }
1119 return ERR_OK;
1120}
1121
1122/**
1123 * Deallocates a list of TCP segments (tcp_seg structures).
1124 *
1125 * @param seg tcp_seg list of TCP segments to free
1126 */
1127void
1128tcp_segs_free(struct tcp_seg *seg)
1129{
1130 while (seg != NULL) {
1131 struct tcp_seg *next = seg->next;
1132 tcp_seg_free(seg);
1133 seg = next;
1134 }
1135}
1136
1137/**
1138 * Frees a TCP segment (tcp_seg structure).
1139 *
1140 * @param seg single tcp_seg to free
1141 */
1142void
1143tcp_seg_free(struct tcp_seg *seg)
1144{
1145 if (seg != NULL) {
1146 if (seg->p != NULL) {
1147 pbuf_free(seg->p);
1148#if TCP_DEBUG
1149 seg->p = NULL;
1150#endif /* TCP_DEBUG */
1151 }
1152 memp_free(MEMP_TCP_SEG, seg);
1153 }
1154}
1155
1156/**
1157 * Sets the priority of a connection.
1158 *
1159 * @param pcb the tcp_pcb to manipulate
1160 * @param prio new priority
1161 */
1162void
1163tcp_setprio(struct tcp_pcb *pcb, u8_t prio)
1164{
1165 pcb->prio = prio;
1166}
1167
1168#if TCP_QUEUE_OOSEQ
1169/**
1170 * Returns a copy of the given TCP segment.
1171 * The pbuf and data are not copied, only the pointers
1172 *
1173 * @param seg the old tcp_seg
1174 * @return a copy of seg
1175 */
1176struct tcp_seg *
1177tcp_seg_copy(struct tcp_seg *seg)
1178{
1179 struct tcp_seg *cseg;
1180
1181 cseg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG);
1182 if (cseg == NULL) {
1183 return NULL;
1184 }
1185 SMEMCPY((u8_t *)cseg, (const u8_t *)seg, sizeof(struct tcp_seg));
1186 pbuf_ref(cseg->p);
1187 return cseg;
1188}
1189#endif /* TCP_QUEUE_OOSEQ */
1190
1191#if LWIP_CALLBACK_API
1192/**
1193 * Default receive callback that is called if the user didn't register
1194 * a recv callback for the pcb.
1195 */
1196err_t
1197tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
1198{
1199 LWIP_UNUSED_ARG(arg);
1200 if (p != NULL) {
1201 tcp_recved(pcb, p->tot_len);
1202 pbuf_free(p);
1203 } else if (err == ERR_OK) {
1204 return tcp_close(pcb);
1205 }
1206 return ERR_OK;
1207}
1208#endif /* LWIP_CALLBACK_API */
1209
1210/**
1211 * Kills the oldest active connection that has the same or lower priority than
1212 * 'prio'.
1213 *
1214 * @param prio minimum priority
1215 */
1216static void
1217tcp_kill_prio(u8_t prio)
1218{
1219 struct tcp_pcb *pcb, *inactive;
1220 u32_t inactivity;
1221 u8_t mprio;
1222
1223
1224 mprio = TCP_PRIO_MAX;
1225
1226 /* We kill the oldest active connection that has lower priority than prio. */
1227 inactivity = 0;
1228 inactive = NULL;
1229 for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
1230 if (pcb->prio <= prio &&
1231 pcb->prio <= mprio &&
1232 (u32_t)(tcp_ticks - pcb->tmr) >= inactivity) {
1233 inactivity = tcp_ticks - pcb->tmr;
1234 inactive = pcb;
1235 mprio = pcb->prio;
1236 }
1237 }
1238 if (inactive != NULL) {
1239 LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB %p (%"S32_F")\n",
1240 (void *)inactive, inactivity));
1241 tcp_abort(inactive);
1242 }
1243}
1244
1245/**
1246 * Kills the oldest connection that is in TIME_WAIT state.
1247 * Called from tcp_alloc() if no more connections are available.
1248 */
1249static void
1250tcp_kill_timewait(void)
1251{
1252 struct tcp_pcb *pcb, *inactive;
1253 u32_t inactivity;
1254
1255 inactivity = 0;
1256 inactive = NULL;
1257 /* Go through the list of TIME_WAIT pcbs and get the oldest pcb. */
1258 for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
1259 if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) {
1260 inactivity = tcp_ticks - pcb->tmr;
1261 inactive = pcb;
1262 }
1263 }
1264 if (inactive != NULL) {
1265 LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB %p (%"S32_F")\n",
1266 (void *)inactive, inactivity));
1267 tcp_abort(inactive);
1268 }
1269}
1270
1271/**
1272 * Allocate a new tcp_pcb structure.
1273 *
1274 * @param prio priority for the new pcb
1275 * @return a new tcp_pcb that initially is in state CLOSED
1276 */
1277struct tcp_pcb *
1278tcp_alloc(u8_t prio)
1279{
1280 struct tcp_pcb *pcb;
1281 u32_t iss;
1282
1283 pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
1284 if (pcb == NULL) {
1285 /* Try killing oldest connection in TIME-WAIT. */
1286 LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest TIME-WAIT connection\n"));
1287 tcp_kill_timewait();
1288 /* Try to allocate a tcp_pcb again. */
1289 pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
1290 if (pcb == NULL) {
1291 /* Try killing active connections with lower priority than the new one. */
1292 LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing connection with prio lower than %d\n", prio));
1293 tcp_kill_prio(prio);
1294 /* Try to allocate a tcp_pcb again. */
1295 pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
1296 if (pcb != NULL) {
1297 /* adjust err stats: memp_malloc failed twice before */
1298 MEMP_STATS_DEC(err, MEMP_TCP_PCB);
1299 }
1300 }
1301 if (pcb != NULL) {
1302 /* adjust err stats: timewait PCB was freed above */
1303 MEMP_STATS_DEC(err, MEMP_TCP_PCB);
1304 }
1305 }
1306 if (pcb != NULL) {
1307 memset(pcb, 0, sizeof(struct tcp_pcb));
1308 pcb->prio = prio;
1309 pcb->snd_buf = TCP_SND_BUF;
1310 pcb->snd_queuelen = 0;
1311 pcb->rcv_wnd = TCP_WND;
1312 pcb->rcv_ann_wnd = TCP_WND;
1313 pcb->tos = 0;
1314 pcb->ttl = TCP_TTL;
1315 /* As initial send MSS, we use TCP_MSS but limit it to 536.
1316 The send MSS is updated when an MSS option is received. */
1317 pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS;
1318 pcb->rto = 3000 / TCP_SLOW_INTERVAL;
1319 pcb->sa = 0;
1320 pcb->sv = 3000 / TCP_SLOW_INTERVAL;
1321 pcb->rtime = -1;
1322 pcb->cwnd = 1;
1323 iss = tcp_next_iss();
1324 pcb->snd_wl2 = iss;
1325 pcb->snd_nxt = iss;
1326 pcb->lastack = iss;
1327 pcb->snd_lbb = iss;
1328 pcb->tmr = tcp_ticks;
1329 pcb->last_timer = tcp_timer_ctr;
1330
1331 pcb->polltmr = 0;
1332
1333#if LWIP_CALLBACK_API
1334 pcb->recv = tcp_recv_null;
1335#endif /* LWIP_CALLBACK_API */
1336
1337 /* Init KEEPALIVE timer */
1338 pcb->keep_idle = TCP_KEEPIDLE_DEFAULT;
1339
1340#if LWIP_TCP_KEEPALIVE
1341 pcb->keep_intvl = TCP_KEEPINTVL_DEFAULT;
1342 pcb->keep_cnt = TCP_KEEPCNT_DEFAULT;
1343#endif /* LWIP_TCP_KEEPALIVE */
1344
1345 pcb->keep_cnt_sent = 0;
1346 }
1347 return pcb;
1348}
1349
1350/**
1351 * Creates a new TCP protocol control block but doesn't place it on
1352 * any of the TCP PCB lists.
1353 * The pcb is not put on any list until binding using tcp_bind().
1354 *
1355 * @internal: Maybe there should be a idle TCP PCB list where these
1356 * PCBs are put on. Port reservation using tcp_bind() is implemented but
1357 * allocated pcbs that are not bound can't be killed automatically if wanting
1358 * to allocate a pcb with higher prio (@see tcp_kill_prio())
1359 *
1360 * @return a new tcp_pcb that initially is in state CLOSED
1361 */
1362struct tcp_pcb *
1363tcp_new(void)
1364{
1365 return tcp_alloc(TCP_PRIO_NORMAL);
1366}
1367
1368/**
1369 * Used to specify the argument that should be passed callback
1370 * functions.
1371 *
1372 * @param pcb tcp_pcb to set the callback argument
1373 * @param arg void pointer argument to pass to callback functions
1374 */
1375void
1376tcp_arg(struct tcp_pcb *pcb, void *arg)
1377{
1378 /* This function is allowed to be called for both listen pcbs and
1379 connection pcbs. */
1380 pcb->callback_arg = arg;
1381}
1382#if LWIP_CALLBACK_API
1383
1384/**
1385 * Used to specify the function that should be called when a TCP
1386 * connection receives data.
1387 *
1388 * @param pcb tcp_pcb to set the recv callback
1389 * @param recv callback function to call for this pcb when data is received
1390 */
1391void
1392tcp_recv(struct tcp_pcb *pcb, tcp_recv_fn recv)
1393{
1394 LWIP_ASSERT("invalid socket state for recv callback", pcb->state != LISTEN);
1395 pcb->recv = recv;
1396}
1397
1398/**
1399 * Used to specify the function that should be called when TCP data
1400 * has been successfully delivered to the remote host.
1401 *
1402 * @param pcb tcp_pcb to set the sent callback
1403 * @param sent callback function to call for this pcb when data is successfully sent
1404 */
1405void
1406tcp_sent(struct tcp_pcb *pcb, tcp_sent_fn sent)
1407{
1408 LWIP_ASSERT("invalid socket state for sent callback", pcb->state != LISTEN);
1409 pcb->sent = sent;
1410}
1411
1412/**
1413 * Used to specify the function that should be called when a fatal error
1414 * has occured on the connection.
1415 *
1416 * @param pcb tcp_pcb to set the err callback
1417 * @param err callback function to call for this pcb when a fatal error
1418 * has occured on the connection
1419 */
1420void
1421tcp_err(struct tcp_pcb *pcb, tcp_err_fn err)
1422{
1423 LWIP_ASSERT("invalid socket state for err callback", pcb->state != LISTEN);
1424 pcb->errf = err;
1425}
1426
1427/**
1428 * Used for specifying the function that should be called when a
1429 * LISTENing connection has been connected to another host.
1430 *
1431 * @param pcb tcp_pcb to set the accept callback
1432 * @param accept callback function to call for this pcb when LISTENing
1433 * connection has been connected to another host
1434 */
1435void
1436tcp_accept(struct tcp_pcb *pcb, tcp_accept_fn accept)
1437{
1438 /* This function is allowed to be called for both listen pcbs and
1439 connection pcbs. */
1440 pcb->accept = accept;
1441}
1442#endif /* LWIP_CALLBACK_API */
1443
1444
1445/**
1446 * Used to specify the function that should be called periodically
1447 * from TCP. The interval is specified in terms of the TCP coarse
1448 * timer interval, which is called twice a second.
1449 *
1450 */
1451void
1452tcp_poll(struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval)
1453{
1454 LWIP_ASSERT("invalid socket state for poll", pcb->state != LISTEN);
1455#if LWIP_CALLBACK_API
1456 pcb->poll = poll;
1457#else /* LWIP_CALLBACK_API */
1458 LWIP_UNUSED_ARG(poll);
1459#endif /* LWIP_CALLBACK_API */
1460 pcb->pollinterval = interval;
1461}
1462
1463/**
1464 * Purges a TCP PCB. Removes any buffered data and frees the buffer memory
1465 * (pcb->ooseq, pcb->unsent and pcb->unacked are freed).
1466 *
1467 * @param pcb tcp_pcb to purge. The pcb itself is not deallocated!
1468 */
1469void
1470tcp_pcb_purge(struct tcp_pcb *pcb)
1471{
1472 if (pcb->state != CLOSED &&
1473 pcb->state != TIME_WAIT &&
1474 pcb->state != LISTEN) {
1475
1476 LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge\n"));
1477
1478#if TCP_LISTEN_BACKLOG
1479 if (pcb->state == SYN_RCVD) {
1480 /* Need to find the corresponding listen_pcb and decrease its accepts_pending */
1481 struct tcp_pcb_listen *lpcb;
1482 LWIP_ASSERT("tcp_pcb_purge: pcb->state == SYN_RCVD but tcp_listen_pcbs is NULL",
1483 tcp_listen_pcbs.listen_pcbs != NULL);
1484 for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
1485 if ((lpcb->local_port == pcb->local_port) &&
1486 (ip_addr_isany(&lpcb->local_ip) ||
1487 ip_addr_cmp(&pcb->local_ip, &lpcb->local_ip))) {
1488 /* port and address of the listen pcb match the timed-out pcb */
1489 LWIP_ASSERT("tcp_pcb_purge: listen pcb does not have accepts pending",
1490 lpcb->accepts_pending > 0);
1491 lpcb->accepts_pending--;
1492 break;
1493 }
1494 }
1495 }
1496#endif /* TCP_LISTEN_BACKLOG */
1497
1498
1499 if (pcb->refused_data != NULL) {
1500 LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->refused_data\n"));
1501 pbuf_free(pcb->refused_data);
1502 pcb->refused_data = NULL;
1503 }
1504 if (pcb->unsent != NULL) {
1505 LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: not all data sent\n"));
1506 }
1507 if (pcb->unacked != NULL) {
1508 LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->unacked\n"));
1509 }
1510#if TCP_QUEUE_OOSEQ
1511 if (pcb->ooseq != NULL) {
1512 LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n"));
1513 }
1514 tcp_segs_free(pcb->ooseq);
1515 pcb->ooseq = NULL;
1516#endif /* TCP_QUEUE_OOSEQ */
1517
1518 /* Stop the retransmission timer as it will expect data on unacked
1519 queue if it fires */
1520 pcb->rtime = -1;
1521
1522 tcp_segs_free(pcb->unsent);
1523 tcp_segs_free(pcb->unacked);
1524 pcb->unacked = pcb->unsent = NULL;
1525#if TCP_OVERSIZE
1526 pcb->unsent_oversize = 0;
1527#endif /* TCP_OVERSIZE */
1528 }
1529}
1530
1531/**
1532 * Purges the PCB and removes it from a PCB list. Any delayed ACKs are sent first.
1533 *
1534 * @param pcblist PCB list to purge.
1535 * @param pcb tcp_pcb to purge. The pcb itself is NOT deallocated!
1536 */
1537void
1538tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb)
1539{
1540 TCP_RMV(pcblist, pcb);
1541
1542 tcp_pcb_purge(pcb);
1543
1544 /* if there is an outstanding delayed ACKs, send it */
1545 if (pcb->state != TIME_WAIT &&
1546 pcb->state != LISTEN &&
1547 pcb->flags & TF_ACK_DELAY) {
1548 pcb->flags |= TF_ACK_NOW;
1549 tcp_output(pcb);
1550 }
1551
1552 if (pcb->state != LISTEN) {
1553 LWIP_ASSERT("unsent segments leaking", pcb->unsent == NULL);
1554 LWIP_ASSERT("unacked segments leaking", pcb->unacked == NULL);
1555#if TCP_QUEUE_OOSEQ
1556 LWIP_ASSERT("ooseq segments leaking", pcb->ooseq == NULL);
1557#endif /* TCP_QUEUE_OOSEQ */
1558 }
1559
1560 pcb->state = CLOSED;
1561
1562 LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane());
1563}
1564
1565/**
1566 * Calculates a new initial sequence number for new connections.
1567 *
1568 * @return u32_t pseudo random sequence number
1569 */
1570u32_t
1571tcp_next_iss(void)
1572{
1573 static u32_t iss = 6510;
1574
1575 iss += tcp_ticks; /* XXX */
1576 return iss;
1577}
1578
1579#if TCP_CALCULATE_EFF_SEND_MSS
1580/**
1581 * Calcluates the effective send mss that can be used for a specific IP address
1582 * by using ip_route to determin the netif used to send to the address and
1583 * calculating the minimum of TCP_MSS and that netif's mtu (if set).
1584 */
1585u16_t
1586tcp_eff_send_mss(u16_t sendmss, ip_addr_t *addr)
1587{
1588 u16_t mss_s;
1589 struct netif *outif;
1590
1591 outif = ip_route(addr);
1592 if ((outif != NULL) && (outif->mtu != 0)) {
1593 mss_s = outif->mtu - IP_HLEN - TCP_HLEN;
1594 /* RFC 1122, chap 4.2.2.6:
1595 * Eff.snd.MSS = min(SendMSS+20, MMS_S) - TCPhdrsize - IPoptionsize
1596 * We correct for TCP options in tcp_write(), and don't support IP options.
1597 */
1598 sendmss = LWIP_MIN(sendmss, mss_s);
1599 }
1600 return sendmss;
1601}
1602#endif /* TCP_CALCULATE_EFF_SEND_MSS */
1603
1604const char*
1605tcp_debug_state_str(enum tcp_state s)
1606{
1607 return tcp_state_str[s];
1608}
1609
1610#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG
1611/**
1612 * Print a tcp header for debugging purposes.
1613 *
1614 * @param tcphdr pointer to a struct tcp_hdr
1615 */
1616void
1617tcp_debug_print(struct tcp_hdr *tcphdr)
1618{
1619 LWIP_DEBUGF(TCP_DEBUG, ("TCP header:\n"));
1620 LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
1621 LWIP_DEBUGF(TCP_DEBUG, ("| %5"U16_F" | %5"U16_F" | (src port, dest port)\n",
1622 ntohs(tcphdr->src), ntohs(tcphdr->dest)));
1623 LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
1624 LWIP_DEBUGF(TCP_DEBUG, ("| %010"U32_F" | (seq no)\n",
1625 ntohl(tcphdr->seqno)));
1626 LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
1627 LWIP_DEBUGF(TCP_DEBUG, ("| %010"U32_F" | (ack no)\n",
1628 ntohl(tcphdr->ackno)));
1629 LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
1630 LWIP_DEBUGF(TCP_DEBUG, ("| %2"U16_F" | |%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"| %5"U16_F" | (hdrlen, flags (",
1631 TCPH_HDRLEN(tcphdr),
1632 TCPH_FLAGS(tcphdr) >> 5 & 1,
1633 TCPH_FLAGS(tcphdr) >> 4 & 1,
1634 TCPH_FLAGS(tcphdr) >> 3 & 1,
1635 TCPH_FLAGS(tcphdr) >> 2 & 1,
1636 TCPH_FLAGS(tcphdr) >> 1 & 1,
1637 TCPH_FLAGS(tcphdr) & 1,
1638 ntohs(tcphdr->wnd)));
1639 tcp_debug_print_flags(TCPH_FLAGS(tcphdr));
1640 LWIP_DEBUGF(TCP_DEBUG, ("), win)\n"));
1641 LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
1642 LWIP_DEBUGF(TCP_DEBUG, ("| 0x%04"X16_F" | %5"U16_F" | (chksum, urgp)\n",
1643 ntohs(tcphdr->chksum), ntohs(tcphdr->urgp)));
1644 LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
1645}
1646
1647/**
1648 * Print a tcp state for debugging purposes.
1649 *
1650 * @param s enum tcp_state to print
1651 */
1652void
1653tcp_debug_print_state(enum tcp_state s)
1654{
1655 LWIP_DEBUGF(TCP_DEBUG, ("State: %s\n", tcp_state_str[s]));
1656}
1657
1658/**
1659 * Print tcp flags for debugging purposes.
1660 *
1661 * @param flags tcp flags, all active flags are printed
1662 */
1663void
1664tcp_debug_print_flags(u8_t flags)
1665{
1666 if (flags & TCP_FIN) {
1667 LWIP_DEBUGF(TCP_DEBUG, ("FIN "));
1668 }
1669 if (flags & TCP_SYN) {
1670 LWIP_DEBUGF(TCP_DEBUG, ("SYN "));
1671 }
1672 if (flags & TCP_RST) {
1673 LWIP_DEBUGF(TCP_DEBUG, ("RST "));
1674 }
1675 if (flags & TCP_PSH) {
1676 LWIP_DEBUGF(TCP_DEBUG, ("PSH "));
1677 }
1678 if (flags & TCP_ACK) {
1679 LWIP_DEBUGF(TCP_DEBUG, ("ACK "));
1680 }
1681 if (flags & TCP_URG) {
1682 LWIP_DEBUGF(TCP_DEBUG, ("URG "));
1683 }
1684 if (flags & TCP_ECE) {
1685 LWIP_DEBUGF(TCP_DEBUG, ("ECE "));
1686 }
1687 if (flags & TCP_CWR) {
1688 LWIP_DEBUGF(TCP_DEBUG, ("CWR "));
1689 }
1690 LWIP_DEBUGF(TCP_DEBUG, ("\n"));
1691}
1692
1693/**
1694 * Print all tcp_pcbs in every list for debugging purposes.
1695 */
1696void
1697tcp_debug_print_pcbs(void)
1698{
1699 struct tcp_pcb *pcb;
1700 LWIP_DEBUGF(TCP_DEBUG, ("Active PCB states:\n"));
1701 for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
1702 LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
1703 pcb->local_port, pcb->remote_port,
1704 pcb->snd_nxt, pcb->rcv_nxt));
1705 tcp_debug_print_state(pcb->state);
1706 }
1707 LWIP_DEBUGF(TCP_DEBUG, ("Listen PCB states:\n"));
1708 for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) {
1709 LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
1710 pcb->local_port, pcb->remote_port,
1711 pcb->snd_nxt, pcb->rcv_nxt));
1712 tcp_debug_print_state(pcb->state);
1713 }
1714 LWIP_DEBUGF(TCP_DEBUG, ("TIME-WAIT PCB states:\n"));
1715 for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
1716 LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
1717 pcb->local_port, pcb->remote_port,
1718 pcb->snd_nxt, pcb->rcv_nxt));
1719 tcp_debug_print_state(pcb->state);
1720 }
1721}
1722
1723/**
1724 * Check state consistency of the tcp_pcb lists.
1725 */
1726s16_t
1727tcp_pcbs_sane(void)
1728{
1729 struct tcp_pcb *pcb;
1730 for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
1731 LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != CLOSED", pcb->state != CLOSED);
1732 LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != LISTEN", pcb->state != LISTEN);
1733 LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
1734 }
1735 for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
1736 LWIP_ASSERT("tcp_pcbs_sane: tw pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
1737 }
1738 return 1;
1739}
1740#endif /* TCP_DEBUG */
1741
1742#endif /* LWIP_TCP */
Note: See TracBrowser for help on using the repository browser.