ReactOS 0.4.15-dev-7958-gcd0bb1a
tcp.c
Go to the documentation of this file.
1
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
101struct tcp_pcb *tcp_bound_pcbs;
103union tcp_listen_pcbs_t tcp_listen_pcbs;
106struct tcp_pcb *tcp_active_pcbs;
108struct tcp_pcb *tcp_tw_pcbs;
109
110#define NUM_TCP_PCB_LISTS 4
111#define NUM_TCP_PCB_LISTS_NO_TIME_WAIT 3
113struct tcp_pcb ** const tcp_pcb_lists[] = {&tcp_listen_pcbs.pcbs, &tcp_bound_pcbs,
114 &tcp_active_pcbs, &tcp_tw_pcbs};
115
117struct tcp_pcb *tcp_tmp_pcb;
118
119u8_t tcp_active_pcbs_changed;
120
122static u8_t tcp_timer;
123static u8_t tcp_timer_ctr;
124static u16_t tcp_new_port(void);
125
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
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
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;
227 break;
228 case SYN_RCVD:
229 err = tcp_send_fin(pcb);
230 if (err == ERR_OK) {
232 pcb->state = FIN_WAIT_1;
233 }
234 break;
235 case ESTABLISHED:
236 err = tcp_send_fin(pcb);
237 if (err == ERR_OK) {
239 pcb->state = FIN_WAIT_1;
240 }
241 break;
242 case CLOSE_WAIT:
243 err = tcp_send_fin(pcb);
244 if (err == ERR_OK) {
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
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
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
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
412void
413tcp_abort(struct tcp_pcb *pcb)
414{
415 tcp_abandon(pcb, 1);
416}
417
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) ||
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
493static err_t
494tcp_accept_null(void *arg, struct tcp_pcb *pcb, err_t err)
495{
497 LWIP_UNUSED_ARG(pcb);
499
500 return ERR_ABRT;
501}
502#endif /* LWIP_CALLBACK_API */
503
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;
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
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
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
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
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 */
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);
774
775 tcp_output(pcb);
776 }
777 return ret;
778}
779
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
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
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
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
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
1162void
1163tcp_setprio(struct tcp_pcb *pcb, u8_t prio)
1164{
1165 pcb->prio = prio;
1166}
1167
1168#if TCP_QUEUE_OOSEQ
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
1196err_t
1197tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
1198{
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
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
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
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
1362struct tcp_pcb *
1363tcp_new(void)
1364{
1365 return tcp_alloc(TCP_PRIO_NORMAL);
1366}
1367
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
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
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
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
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
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 */
1459#endif /* LWIP_CALLBACK_API */
1460 pcb->pollinterval = interval;
1461}
1462
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
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
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
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
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
1652void
1653tcp_debug_print_state(enum tcp_state s)
1654{
1655 LWIP_DEBUGF(TCP_DEBUG, ("State: %s\n", tcp_state_str[s]));
1656}
1657
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
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
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 */
@ sent
Definition: SystemMenu.c:27
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:73
STREAM tcp_recv(STREAM s, uint32 length)
Definition: tcp.c:344
RD_BOOL tcp_connect(char *server)
Definition: tcp.c:717
STREAM tcp_init(uint32 maxlen)
Definition: tcp.c:82
#define LWIP_MIN(x, y)
Definition: def.h:44
#define NULL
Definition: types.h:112
USHORT port
Definition: uri.c:228
INT WSAAPI recv(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags)
Definition: recv.c:23
#define X16_F
Definition: cc.h:38
signed short s16_t
Definition: cc.h:29
#define S32_F
Definition: cc.h:40
#define U16_F
Definition: cc.h:36
#define S16_F
Definition: cc.h:37
unsigned long u32_t
Definition: cc.h:25
#define U32_F
Definition: cc.h:39
unsigned char u8_t
Definition: cc.h:23
unsigned short u16_t
Definition: cc.h:24
static const char *const tcp_state_str[]
Definition: tcp.c:6
#define ip_set_option(pcb, opt)
Definition: ip.h:207
#define SOF_KEEPALIVE
Definition: ip.h:100
#define ip_get_option(pcb, opt)
Definition: ip.h:205
#define SOF_REUSEADDR
Definition: ip.h:99
#define SOF_ACCEPTCONN
Definition: ip.h:98
#define IP_HLEN
Definition: ip.h:50
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:95
#define LWIP_ERROR(message, expression, handler)
Definition: debug.h:74
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:66
#define ERR_ABRT
Definition: err.h:65
#define ERR_ISCONN
Definition: err.h:61
#define ERR_USE
Definition: err.h:60
#define ERR_CONN
Definition: err.h:68
#define ERR_OK
Definition: err.h:52
#define ERR_RTE
Definition: err.h:56
#define ERR_VAL
Definition: err.h:58
#define ERR_BUF
Definition: err.h:54
s8_t err_t
Definition: err.h:47
#define snmp_inc_tcpattemptfails()
Definition: snmp.h:313
#define snmp_inc_tcpestabresets()
Definition: snmp.h:314
#define snmp_inc_tcpactiveopens()
Definition: snmp.h:311
int connected
Definition: main.c:61
GLdouble s
Definition: gl.h:2039
GLdouble n
Definition: glext.h:7729
GLboolean reset
Definition: glext.h:5666
GLbitfield flags
Definition: glext.h:7161
GLenum const GLvoid * addr
Definition: glext.h:9621
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define TCP_MAXRTX
Definition: lwipopts.h:71
#define TCP_RST_DEBUG
Definition: lwipopts.h:196
#define TCP_DEBUG
Definition: lwipopts.h:160
#define TCP_SYNMAXRTX
Definition: lwipopts.h:73
#define TCP_CWND_DEBUG
Definition: lwipopts.h:181
#define TCP_WND
Definition: lwipopts.h:67
#define TCP_SND_BUF
Definition: lwipopts.h:69
#define TCP_RTO_DEBUG
Definition: lwipopts.h:176
#define TCP_MSS
Definition: lwipopts.h:65
#define TCP_INPUT_DEBUG
Definition: lwipopts.h:165
#define ip_addr_cmp(addr1, addr2)
Definition: ip_addr.h:198
#define ip_addr_isany(addr1)
Definition: ip_addr.h:200
#define ip4_addr1_16(ipaddr)
Definition: ip_addr.h:226
#define ip4_addr2_16(ipaddr)
Definition: ip_addr.h:227
#define ip_addr_copy(dest, src)
Definition: ip_addr.h:162
typedefPACK_STRUCT_END struct ip_addr ip_addr_t
Definition: ip_addr.h:64
#define ip4_addr3_16(ipaddr)
Definition: ip_addr.h:228
#define ip4_addr4_16(ipaddr)
Definition: ip_addr.h:229
struct netif * ip_route(ip_addr_t *dest)
Definition: ip.c:124
void * memp_malloc(memp_t type)
Definition: memp.c:390
void memp_free(memp_t type, void *mem)
Definition: memp.c:435
#define ntohl(x)
Definition: module.h:205
#define ntohs(x)
Definition: module.h:210
#define TCP_WND_UPDATE_THRESHOLD
Definition: opt.h:1068
#define SMEMCPY(dst, src, len)
Definition: opt.h:92
#define TCP_TTL
Definition: opt.h:915
void pbuf_ref(struct pbuf *p)
Definition: pbuf.c:723
u8_t pbuf_free(struct pbuf *p)
Definition: pbuf.c:618
#define PBUF_FLAG_TCP_FIN
Definition: pbuf.h:77
static unsigned __int64 next
Definition: rand_nt.c:6
#define err(...)
#define memset(x, y, z)
Definition: compat.h:39
SOCKET WSAAPI accept(IN SOCKET s, OUT LPSOCKADDR addr, OUT INT FAR *addrlen)
Definition: socklife.c:23
#define MEMP_STATS_DEC(x, i)
Definition: stats.h:254
struct define * next
Definition: compiler.c:65
Definition: netif.h:136
ip_addr_t ip_addr
Definition: netif.h:141
u16_t mtu
Definition: netif.h:186
Definition: pbuf.h:79
Definition: tcpdef.h:22
__u16 dest
Definition: tcpdef.h:24
void tcp_close(struct sock *sk, long timeout)
struct sock * tcp_accept(struct sock *sk, int flags, int *err)
void tcp_shutdown(struct sock *sk, int how)
void tcp_send_fin(struct sock *sk)
unsigned int tcp_poll(struct file *file, struct socket *sock, struct poll_table_struct *wait)
int ret
void * arg
Definition: msvc.h:10
#define poll
Definition: wintirpc.h:59