4 * Transmission Control Protocol for IP
8 * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
11 * Redistribution and use in source and binary forms, with or without modification,
12 * are permitted provided that the following conditions are met:
14 * 1. Redistributions of source code must retain the above copyright notice,
15 * this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright notice,
17 * this list of conditions and the following disclaimer in the documentation
18 * and/or other materials provided with the distribution.
19 * 3. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
25 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
27 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
33 * This file is part of the lwIP TCP/IP stack.
35 * Author: Adam Dunkels <adam@sics.se>
42 * This file contains common functions for the TCP implementation, such as functinos
43 * for manipulating the data structures and the TCP timer functions. TCP functions
44 * related to input and output is found in tcp_input.c and tcp_output.c respectively.
53 #include "lwip/memp.h"
65 /* Incremented every coarse grained timer shot
66 (typically every 500 ms, determined by TCP_COARSE_TIMEOUT). */
69 const u8_t tcp_backoff
[13] =
70 { 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7};
72 /* The TCP PCB lists. */
73 struct tcp_pcb_listen
*tcp_listen_pcbs
; /* List of all TCP PCBs in LISTEN state. */
74 struct tcp_pcb
*tcp_active_pcbs
; /* List of all TCP PCBs that are in a
75 state in which they accept or send
77 struct tcp_pcb
*tcp_tw_pcbs
; /* List of all TCP PCBs in TIME-WAIT. */
79 struct tcp_pcb
*tcp_tmp_pcb
;
81 static u8_t tcp_timer
;
83 static u16_t
tcp_new_port(void);
88 * Initializes the TCP layer.
95 tcp_listen_pcbs
= NULL
;
96 tcp_active_pcbs
= NULL
;
100 /* initialize timer */
109 * Called periodically to dispatch TCP timers.
116 /* Call tcp_fasttmr() every 250 ms */
119 if (++tcp_timer
& 1) {
120 /* Call tcp_tmr() every 500 ms, i.e., every other timer
121 tcp_tmr() is called. */
129 * Closes the connection held by the PCB.
134 tcp_close(struct tcp_pcb
*pcb
)
139 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_close: closing in state "));
140 tcp_debug_print_state(pcb
->state
);
141 LWIP_DEBUGF(TCP_DEBUG
, ("\n"));
142 #endif /* TCP_DEBUG */
143 switch (pcb
->state
) {
146 tcp_pcb_remove((struct tcp_pcb
**)&tcp_listen_pcbs
, pcb
);
147 memp_free(MEMP_TCP_PCB_LISTEN
, pcb
);
152 tcp_pcb_remove(&tcp_active_pcbs
, pcb
);
153 memp_free(MEMP_TCP_PCB
, pcb
);
158 err
= tcp_send_ctrl(pcb
, TCP_FIN
);
160 pcb
->state
= FIN_WAIT_1
;
164 err
= tcp_send_ctrl(pcb
, TCP_FIN
);
166 pcb
->state
= LAST_ACK
;
170 /* Has already been closed, do nothing. */
176 if (pcb
!= NULL
&& err
== ERR_OK
) {
177 err
= tcp_output(pcb
);
185 * Aborts a connection by sending a RST to the remote host and deletes
186 * the local protocol control block. This is done when a connection is
187 * killed because of shortage of memory.
192 tcp_abort(struct tcp_pcb
*pcb
)
195 u16_t remote_port
, local_port
;
196 struct ip_addr remote_ip
, local_ip
;
197 #if LWIP_CALLBACK_API
198 void (* errf
)(void *arg
, err_t err
);
199 #endif /* LWIP_CALLBACK_API */
203 /* Figure out on which TCP PCB list we are, and remove us. If we
204 are in an active state, call the receive function associated with
205 the PCB with a NULL argument, and send an RST to the remote end. */
206 if (pcb
->state
== TIME_WAIT
) {
207 tcp_pcb_remove(&tcp_tw_pcbs
, pcb
);
208 memp_free(MEMP_TCP_PCB
, pcb
);
210 seqno
= pcb
->snd_nxt
;
211 ackno
= pcb
->rcv_nxt
;
212 ip_addr_set(&local_ip
, &(pcb
->local_ip
));
213 ip_addr_set(&remote_ip
, &(pcb
->remote_ip
));
214 local_port
= pcb
->local_port
;
215 remote_port
= pcb
->remote_port
;
216 #if LWIP_CALLBACK_API
218 #endif /* LWIP_CALLBACK_API */
219 errf_arg
= pcb
->callback_arg
;
220 tcp_pcb_remove(&tcp_active_pcbs
, pcb
);
221 if (pcb
->unacked
!= NULL
) {
222 tcp_segs_free(pcb
->unacked
);
224 if (pcb
->unsent
!= NULL
) {
225 tcp_segs_free(pcb
->unsent
);
228 if (pcb
->ooseq
!= NULL
) {
229 tcp_segs_free(pcb
->ooseq
);
231 #endif /* TCP_QUEUE_OOSEQ */
232 memp_free(MEMP_TCP_PCB
, pcb
);
233 TCP_EVENT_ERR(errf
, errf_arg
, ERR_ABRT
);
234 LWIP_DEBUGF(TCP_RST_DEBUG
, ("tcp_abort: sending RST\n"));
235 tcp_rst(seqno
, ackno
, &local_ip
, &remote_ip
, local_port
, remote_port
);
242 * Binds the connection to a local portnumber and IP address. If the
243 * IP address is not given (i.e., ipaddr == NULL), the IP address of
244 * the outgoing network interface is used instead.
249 tcp_bind(struct tcp_pcb
*pcb
, struct ip_addr
*ipaddr
, u16_t port
)
251 struct tcp_pcb
*cpcb
;
253 int reuse_port_all_set
= 1;
254 #endif /* SO_REUSE */
257 port
= tcp_new_port();
260 /* Check if the address already is in use. */
261 for(cpcb
= (struct tcp_pcb
*)tcp_listen_pcbs
;
262 cpcb
!= NULL
; cpcb
= cpcb
->next
) {
263 if (cpcb
->local_port
== port
) {
264 if (ip_addr_isany(&(cpcb
->local_ip
)) ||
265 ip_addr_isany(ipaddr
) ||
266 ip_addr_cmp(&(cpcb
->local_ip
), ipaddr
)) {
271 for(cpcb
= tcp_active_pcbs
;
272 cpcb
!= NULL
; cpcb
= cpcb
->next
) {
273 if (cpcb
->local_port
== port
) {
274 if (ip_addr_isany(&(cpcb
->local_ip
)) ||
275 ip_addr_isany(ipaddr
) ||
276 ip_addr_cmp(&(cpcb
->local_ip
), ipaddr
)) {
282 /* Search through list of PCB's in LISTEN state.
284 If there is a PCB bound to specified port and IP_ADDR_ANY another PCB can be bound to the interface IP
285 or to the loopback address on the same port if SOF_REUSEADDR is set. Any combination of PCB's bound to
286 the same local port, but to one address out of {IP_ADDR_ANY, 127.0.0.1, interface IP} at a time is valid.
287 But no two PCB's bound to same local port and same local address is valid.
289 If SOF_REUSEPORT is set several PCB's can be bound to same local port and same local address also. But then
290 all PCB's must have the SOF_REUSEPORT option set.
292 When the two options aren't set and specified port is already bound, ERR_USE is returned saying that
293 address is already in use. */
294 for(cpcb
= (struct tcp_pcb
*)tcp_listen_pcbs
; cpcb
!= NULL
; cpcb
= cpcb
->next
) {
295 if(cpcb
->local_port
== port
) {
296 if(ip_addr_cmp(&(cpcb
->local_ip
), ipaddr
)) {
297 if(pcb
->so_options
& SOF_REUSEPORT
) {
298 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_bind: in listening PCB's: SO_REUSEPORT set and same address.\n"));
299 reuse_port_all_set
= (reuse_port_all_set
&& (cpcb
->so_options
& SOF_REUSEPORT
));
302 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_bind: in listening PCB's: SO_REUSEPORT not set and same address.\n"));
306 else if((ip_addr_isany(ipaddr
) && !ip_addr_isany(&(cpcb
->local_ip
))) ||
307 (!ip_addr_isany(ipaddr
) && ip_addr_isany(&(cpcb
->local_ip
)))) {
308 if(!(pcb
->so_options
& SOF_REUSEADDR
) && !(pcb
->so_options
& SOF_REUSEPORT
)) {
309 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_bind: in listening PCB's SO_REUSEPORT or SO_REUSEADDR not set and not the same address.\n"));
313 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_bind: in listening PCB's SO_REUSEPORT or SO_REUSEADDR set and not the same address.\n"));
319 /* Search through list of PCB's in a state in which they can accept or send data. Same decription as for
320 PCB's in state LISTEN applies to this PCB's regarding the options SOF_REUSEADDR and SOF_REUSEPORT. */
321 for(cpcb
= tcp_active_pcbs
; cpcb
!= NULL
; cpcb
= cpcb
->next
) {
322 if(cpcb
->local_port
== port
) {
323 if(ip_addr_cmp(&(cpcb
->local_ip
), ipaddr
)) {
324 if(pcb
->so_options
& SOF_REUSEPORT
) {
325 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_bind: in active PCB's SO_REUSEPORT set and same address.\n"));
326 reuse_port_all_set
= (reuse_port_all_set
&& (cpcb
->so_options
& SOF_REUSEPORT
));
329 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_bind: in active PCB's SO_REUSEPORT not set and same address.\n"));
333 else if((ip_addr_isany(ipaddr
) && !ip_addr_isany(&(cpcb
->local_ip
))) ||
334 (!ip_addr_isany(ipaddr
) && ip_addr_isany(&(cpcb
->local_ip
)))) {
335 if(!(pcb
->so_options
& SOF_REUSEADDR
) && !(pcb
->so_options
& SOF_REUSEPORT
)) {
336 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_bind: in active PCB's SO_REUSEPORT or SO_REUSEADDR not set and not the same address.\n"));
340 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_bind: in active PCB's SO_REUSEPORT or SO_REUSEADDR set and not the same address.\n"));
346 /* Search through list of PCB's in TIME_WAIT state. If SO_REUSEADDR is set a bound combination [IP, port}
347 can be rebound. The same applies when SOF_REUSEPORT is set.
349 If SOF_REUSEPORT is set several PCB's can be bound to same local port and same local address also. But then
350 all PCB's must have the SOF_REUSEPORT option set.
352 When the two options aren't set and specified port is already bound, ERR_USE is returned saying that
353 address is already in use. */
354 for(cpcb
= tcp_tw_pcbs
; cpcb
!= NULL
; cpcb
= cpcb
->next
) {
355 if(cpcb
->local_port
== port
) {
356 if(ip_addr_cmp(&(cpcb
->local_ip
), ipaddr
)) {
357 if(!(pcb
->so_options
& SOF_REUSEADDR
) && !(pcb
->so_options
& SOF_REUSEPORT
)) {
358 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_bind: in TIME_WAIT PCB's SO_REUSEPORT or SO_REUSEADDR not set and same address.\n"));
361 else if(pcb
->so_options
& SOF_REUSEPORT
) {
362 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_bind: in TIME_WAIT PCB's SO_REUSEPORT set and same address.\n"));
363 reuse_port_all_set
= (reuse_port_all_set
&& (cpcb
->so_options
& SOF_REUSEPORT
));
369 /* If SOF_REUSEPORT isn't set in all PCB's bound to specified port and local address specified then
370 {IP, port} can't be reused. */
371 if(!reuse_port_all_set
) {
372 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_bind: not all sockets have SO_REUSEPORT set.\n"));
375 #endif /* SO_REUSE */
377 if (!ip_addr_isany(ipaddr
)) {
378 pcb
->local_ip
= *ipaddr
;
380 pcb
->local_port
= port
;
381 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_bind: bind to port %u\n", port
));
384 #if LWIP_CALLBACK_API
386 tcp_accept_null(void *arg
, struct tcp_pcb
*pcb
, err_t err
)
394 #endif /* LWIP_CALLBACK_API */
399 * Set the state of the connection to be LISTEN, which means that it
400 * is able to accept incoming connections. The protocol control block
401 * is reallocated in order to consume less memory. Setting the
402 * connection to LISTEN is an irreversible process.
407 tcp_listen(struct tcp_pcb
*pcb
)
409 struct tcp_pcb_listen
*lpcb
;
411 /* already listening? */
412 if (pcb
->state
== LISTEN
) {
415 lpcb
= memp_malloc(MEMP_TCP_PCB_LISTEN
);
419 lpcb
->callback_arg
= pcb
->callback_arg
;
420 lpcb
->local_port
= pcb
->local_port
;
421 lpcb
->state
= LISTEN
;
422 lpcb
->so_options
= pcb
->so_options
;
423 lpcb
->so_options
|= SOF_ACCEPTCONN
;
424 lpcb
->ttl
= pcb
->ttl
;
425 lpcb
->tos
= pcb
->tos
;
426 ip_addr_set(&lpcb
->local_ip
, &pcb
->local_ip
);
427 memp_free(MEMP_TCP_PCB
, pcb
);
428 #if LWIP_CALLBACK_API
429 lpcb
->accept
= tcp_accept_null
;
430 #endif /* LWIP_CALLBACK_API */
431 TCP_REG(&tcp_listen_pcbs
, lpcb
);
432 return (struct tcp_pcb
*)lpcb
;
438 * This function should be called by the application when it has
439 * processed the data. The purpose is to advertise a larger window
440 * when the data has been processed.
445 tcp_recved(struct tcp_pcb
*pcb
, u16_t len
)
447 if ((u32_t
)pcb
->rcv_wnd
+ len
> TCP_WND
) {
448 pcb
->rcv_wnd
= TCP_WND
;
452 if (pcb
->flags
& TF_ACKNODELAY
) {
454 pcb
->flags
&= ~(TF_ACK_DELAY
| TF_ACK_NOW
);
455 } else if (!(pcb
->flags
& TF_ACK_DELAY
) &&
456 !(pcb
->flags
& TF_ACK_NOW
)) {
460 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_recved: recveived %u bytes, wnd %u (%u).\n",
461 len
, pcb
->rcv_wnd
, TCP_WND
- pcb
->rcv_wnd
));
467 * A nastly hack featuring 'goto' statements that allocates a
468 * new TCP local port.
475 #ifndef TCP_LOCAL_PORT_RANGE_START
476 #define TCP_LOCAL_PORT_RANGE_START 4096
477 #define TCP_LOCAL_PORT_RANGE_END 0x7fff
479 static u16_t port
= TCP_LOCAL_PORT_RANGE_START
;
480 // randomize the port value a bit to avoid TCP conflicts
481 // on lost connections
484 port
+= (tme
.lo
) % 8192;
487 if (++port
> TCP_LOCAL_PORT_RANGE_END
) {
488 port
= TCP_LOCAL_PORT_RANGE_START
;
491 for(pcb
= tcp_active_pcbs
; pcb
!= NULL
; pcb
= pcb
->next
) {
492 if (pcb
->local_port
== port
) {
496 for(pcb
= tcp_tw_pcbs
; pcb
!= NULL
; pcb
= pcb
->next
) {
497 if (pcb
->local_port
== port
) {
501 for(pcb
= (struct tcp_pcb
*)tcp_listen_pcbs
; pcb
!= NULL
; pcb
= pcb
->next
) {
502 if (pcb
->local_port
== port
) {
512 * Connects to another host. The function given as the "connected"
513 * argument will be called when the connection has been established.
518 tcp_connect(struct tcp_pcb
*pcb
, struct ip_addr
*ipaddr
, u16_t port
,
519 err_t (* connected
)(void *arg
, struct tcp_pcb
*tpcb
, err_t err
))
525 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_connect to port %u\n", port
));
526 if (ipaddr
!= NULL
) {
527 pcb
->remote_ip
= *ipaddr
;
531 pcb
->remote_port
= port
;
532 if (pcb
->local_port
== 0) {
533 pcb
->local_port
= tcp_new_port();
535 iss
= tcp_next_iss();
538 pcb
->lastack
= iss
- 1;
539 pcb
->snd_lbb
= iss
- 1;
540 pcb
->rcv_wnd
= TCP_WND
;
541 pcb
->snd_wnd
= TCP_WND
;
544 pcb
->ssthresh
= pcb
->mss
* 10;
545 pcb
->state
= SYN_SENT
;
546 #if LWIP_CALLBACK_API
547 pcb
->connected
= connected
;
548 #endif /* LWIP_CALLBACK_API */
549 TCP_REG(&tcp_active_pcbs
, pcb
);
551 /* Build an MSS option */
552 optdata
= htonl(((u32_t
)2 << 24) |
554 (((u32_t
)pcb
->mss
/ 256) << 8) |
557 ret
= tcp_enqueue(pcb
, NULL
, 0, TCP_SYN
, 0, (u8_t
*)&optdata
, 4);
567 * Called every 500 ms and implements the retransmission timer and the timer that
568 * removes PCBs that have been in TIME-WAIT for enough time. It also increments
569 * various timers such as the inactivity timer in each PCB.
575 struct tcp_pcb
*pcb
, *pcb2
, *prev
;
577 u8_t pcb_remove
; /* flag if a PCB should be removed */
584 /* Steps through all of the active PCBs. */
586 pcb
= tcp_active_pcbs
;
587 if (pcb
== NULL
) LWIP_DEBUGF(TCP_DEBUG
, ("tcp_slowtmr: no active pcbs\n"));
588 while (pcb
!= NULL
) {
589 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_slowtmr: processing active pcb\n"));
590 LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb
->state
!= CLOSED
);
591 LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb
->state
!= LISTEN
);
592 LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb
->state
!= TIME_WAIT
);
596 if (pcb
->state
== SYN_SENT
&& pcb
->nrtx
== TCP_SYNMAXRTX
) {
598 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_slowtmr: max SYN retries reached\n"));
600 else if (pcb
->nrtx
== TCP_MAXRTX
) {
602 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_slowtmr: max DATA retries reached\n"));
605 if (pcb
->unacked
!= NULL
&& pcb
->rtime
>= pcb
->rto
) {
607 /* Time for a retransmission. */
608 LWIP_DEBUGF(TCP_RTO_DEBUG
, ("tcp_slowtmr: rtime %u pcb->rto %u\n",
609 pcb
->rtime
, pcb
->rto
));
611 /* Double retransmission time-out unless we are trying to
612 * connect to somebody (i.e., we are in SYN_SENT). */
613 if (pcb
->state
!= SYN_SENT
) {
614 pcb
->rto
= ((pcb
->sa
>> 3) + pcb
->sv
) << tcp_backoff
[pcb
->nrtx
];
617 /* Reduce congestion window and ssthresh. */
618 eff_wnd
= LWIP_MIN(pcb
->cwnd
, pcb
->snd_wnd
);
619 pcb
->ssthresh
= eff_wnd
>> 1;
620 if (pcb
->ssthresh
< pcb
->mss
) {
621 pcb
->ssthresh
= pcb
->mss
* 2;
623 pcb
->cwnd
= pcb
->mss
;
624 LWIP_DEBUGF(TCP_CWND_DEBUG
, ("tcp_slowtmr: cwnd %u ssthresh %u\n",
625 pcb
->cwnd
, pcb
->ssthresh
));
628 /* Check if this PCB has stayed too long in FIN-WAIT-2 */
629 if (pcb
->state
== FIN_WAIT_2
) {
630 if ((u32_t
)(tcp_ticks
- pcb
->tmr
) >
631 TCP_FIN_WAIT_TIMEOUT
/ TCP_SLOW_INTERVAL
) {
633 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n"));
637 /* Check if KEEPALIVE should be sent */
638 if((pcb
->so_options
& SOF_KEEPALIVE
) && ((pcb
->state
== ESTABLISHED
) || (pcb
->state
== CLOSE_WAIT
))) {
639 if((u32_t
)(tcp_ticks
- pcb
->tmr
) > (pcb
->keepalive
+ TCP_MAXIDLE
) / TCP_SLOW_INTERVAL
) {
640 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to %u.%u.%u.%u.\n",
641 ip4_addr1(&pcb
->remote_ip
), ip4_addr2(&pcb
->remote_ip
),
642 ip4_addr3(&pcb
->remote_ip
), ip4_addr4(&pcb
->remote_ip
)));
646 else if((u32_t
)(tcp_ticks
- pcb
->tmr
) > (pcb
->keepalive
+ pcb
->keep_cnt
* TCP_KEEPINTVL
) / TCP_SLOW_INTERVAL
) {
652 /* If this PCB has queued out of sequence data, but has been
653 inactive for too long, will drop the data (it will eventually
654 be retransmitted). */
656 if (pcb
->ooseq
!= NULL
&&
657 (u32_t
)tcp_ticks
- pcb
->tmr
>=
658 pcb
->rto
* TCP_OOSEQ_TIMEOUT
) {
659 tcp_segs_free(pcb
->ooseq
);
661 LWIP_DEBUGF(TCP_CWND_DEBUG
, ("tcp_slowtmr: dropping OOSEQ queued data\n"));
663 #endif /* TCP_QUEUE_OOSEQ */
665 /* Check if this PCB has stayed too long in SYN-RCVD */
666 if (pcb
->state
== SYN_RCVD
) {
667 if ((u32_t
)(tcp_ticks
- pcb
->tmr
) >
668 TCP_SYN_RCVD_TIMEOUT
/ TCP_SLOW_INTERVAL
) {
670 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n"));
675 /* If the PCB should be removed, do it. */
678 /* Remove PCB from tcp_active_pcbs list. */
680 LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb
!= tcp_active_pcbs
);
681 prev
->next
= pcb
->next
;
683 /* This PCB was the first. */
684 LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs
== pcb
);
685 tcp_active_pcbs
= pcb
->next
;
688 TCP_EVENT_ERR(pcb
->errf
, pcb
->callback_arg
, ERR_ABRT
);
691 memp_free(MEMP_TCP_PCB
, pcb
);
695 /* We check if we should poll the connection. */
697 if (pcb
->polltmr
>= pcb
->pollinterval
) {
699 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_slowtmr: polling application\n"));
700 TCP_EVENT_POLL(pcb
, err
);
712 /* Steps through all of the TIME-WAIT PCBs. */
715 while (pcb
!= NULL
) {
716 LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb
->state
== TIME_WAIT
);
719 /* Check if this PCB has stayed long enough in TIME-WAIT */
720 if ((u32_t
)(tcp_ticks
- pcb
->tmr
) > 2 * TCP_MSL
/ TCP_SLOW_INTERVAL
) {
726 /* If the PCB should be removed, do it. */
729 /* Remove PCB from tcp_tw_pcbs list. */
731 LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb
!= tcp_tw_pcbs
);
732 prev
->next
= pcb
->next
;
734 /* This PCB was the first. */
735 LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs
== pcb
);
736 tcp_tw_pcbs
= pcb
->next
;
739 memp_free(MEMP_TCP_PCB
, pcb
);
751 * Is called every TCP_FAST_INTERVAL (250 ms) and sends delayed ACKs.
759 /* send delayed ACKs */
760 for(pcb
= tcp_active_pcbs
; pcb
!= NULL
; pcb
= pcb
->next
) {
761 if (pcb
->flags
& TF_ACK_DELAY
) {
763 pcb
->flags
&= ~(TF_ACK_DELAY
| TF_ACK_NOW
);
771 * Deallocates a list of TCP segments (tcp_seg structures).
776 tcp_segs_free(struct tcp_seg
*seg
)
779 struct tcp_seg
*next
;
780 while (seg
!= NULL
) {
782 count
+= tcp_seg_free(seg
);
791 * Frees a TCP segment.
796 tcp_seg_free(struct tcp_seg
*seg
)
801 if (seg
->p
!= NULL
) {
802 count
= pbuf_free(seg
->p
);
805 #endif /* TCP_DEBUG */
807 memp_free(MEMP_TCP_SEG
, seg
);
816 * Returns a copy of the given TCP segment.
821 tcp_seg_copy(struct tcp_seg
*seg
)
823 struct tcp_seg
*cseg
;
825 cseg
= memp_malloc(MEMP_TCP_SEG
);
829 mips_memcpy((char *)cseg
, (const char *)seg
, sizeof(struct tcp_seg
));
835 #if LWIP_CALLBACK_API
837 tcp_recv_null(void *arg
, struct tcp_pcb
*pcb
, struct pbuf
*p
, err_t err
)
842 } else if (err
== ERR_OK
) {
843 return tcp_close(pcb
);
847 #endif /* LWIP_CALLBACK_API */
850 tcp_kill_prio(u8_t prio
)
852 struct tcp_pcb
*pcb
, *inactive
;
857 mprio
= TCP_PRIO_MAX
;
859 /* We kill the oldest active connection that has lower priority than
863 for(pcb
= tcp_active_pcbs
; pcb
!= NULL
; pcb
= pcb
->next
) {
864 if (pcb
->prio
<= prio
&&
865 pcb
->prio
<= mprio
&&
866 (u32_t
)(tcp_ticks
- pcb
->tmr
) >= inactivity
) {
867 inactivity
= tcp_ticks
- pcb
->tmr
;
872 if (inactive
!= NULL
) {
873 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_kill_prio: killing oldest PCB 0x%p (%ld)\n",
874 (void *)inactive
, inactivity
));
881 tcp_kill_timewait(void)
883 struct tcp_pcb
*pcb
, *inactive
;
888 for(pcb
= tcp_tw_pcbs
; pcb
!= NULL
; pcb
= pcb
->next
) {
889 if ((u32_t
)(tcp_ticks
- pcb
->tmr
) >= inactivity
) {
890 inactivity
= tcp_ticks
- pcb
->tmr
;
894 if (inactive
!= NULL
) {
895 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB 0x%p (%ld)\n",
896 (void *)inactive
, inactivity
));
909 pcb
= memp_malloc(MEMP_TCP_PCB
);
911 /* Try killing oldest connection in TIME-WAIT. */
912 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_alloc: killing off oldest TIME-WAIT connection\n"));
914 pcb
= memp_malloc(MEMP_TCP_PCB
);
917 pcb
= memp_malloc(MEMP_TCP_PCB
);
921 mips_memset(pcb
, 0, sizeof(struct tcp_pcb
));
922 pcb
->prio
= TCP_PRIO_NORMAL
;
923 pcb
->snd_buf
= TCP_SND_BUF
;
924 pcb
->snd_queuelen
= 0;
925 pcb
->rcv_wnd
= TCP_WND
;
929 pcb
->rto
= 3000 / TCP_SLOW_INTERVAL
;
931 pcb
->sv
= 3000 / TCP_SLOW_INTERVAL
;
934 iss
= tcp_next_iss();
940 pcb
->tmr
= tcp_ticks
;
944 #if LWIP_CALLBACK_API
945 pcb
->recv
= tcp_recv_null
;
946 #endif /* LWIP_CALLBACK_API */
948 /* Init KEEPALIVE timer */
949 pcb
->keepalive
= TCP_KEEPDEFAULT
;
954 #if LWIP_CALLBACK_API
959 * Used to specify the function that should be called when a TCP
960 * connection receives data.
965 tcp_recv(struct tcp_pcb
*pcb
,
966 err_t (* recv
)(void *arg
, struct tcp_pcb
*tpcb
, struct pbuf
*p
, err_t err
))
974 * Used to specify the function that should be called when TCP data
975 * has been successfully delivered to the remote host.
980 tcp_sent(struct tcp_pcb
*pcb
,
981 err_t (* sent
)(void *arg
, struct tcp_pcb
*tpcb
, u16_t len
))
989 * Used to specify the function that should be called when a fatal error
990 * has occured on the connection.
995 tcp_err(struct tcp_pcb
*pcb
,
996 void (* errf
)(void *arg
, err_t err
))
1001 tcp_accept(struct tcp_pcb
*pcb
,
1002 err_t (* accept
)(void *arg
, struct tcp_pcb
*newpcb
, err_t err
))
1004 ((struct tcp_pcb_listen
*)pcb
)->accept
= accept
;
1006 #endif /* LWIP_CALLBACK_API */
1012 * Used to specify the function that should be called periodically
1013 * from TCP. The interval is specified in terms of the TCP coarse
1014 * timer interval, which is called twice a second.
1019 tcp_poll(struct tcp_pcb
*pcb
,
1020 err_t (* poll
)(void *arg
, struct tcp_pcb
*tpcb
), u8_t interval
)
1022 #if LWIP_CALLBACK_API
1024 #endif /* LWIP_CALLBACK_API */
1025 pcb
->pollinterval
= interval
;
1031 * Purges a TCP PCB. Removes any buffered data and frees the buffer memory.
1036 tcp_pcb_purge(struct tcp_pcb
*pcb
)
1038 if (pcb
->state
!= CLOSED
&&
1039 pcb
->state
!= TIME_WAIT
&&
1040 pcb
->state
!= LISTEN
) {
1042 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_pcb_purge\n"));
1044 if (pcb
->unsent
!= NULL
) {
1045 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_pcb_purge: not all data sent\n"));
1047 if (pcb
->unacked
!= NULL
) {
1048 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_pcb_purge: data left on ->unacked\n"));
1050 #if TCP_QUEUE_OOSEQ /* LW */
1051 if (pcb
->ooseq
!= NULL
) {
1052 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_pcb_purge: data left on ->ooseq\n"));
1055 tcp_segs_free(pcb
->ooseq
);
1057 #endif /* TCP_QUEUE_OOSEQ */
1058 tcp_segs_free(pcb
->unsent
);
1059 tcp_segs_free(pcb
->unacked
);
1060 pcb
->unacked
= pcb
->unsent
= NULL
;
1067 * Purges the PCB and removes it from a PCB list. Any delayed ACKs are sent first.
1072 tcp_pcb_remove(struct tcp_pcb
**pcblist
, struct tcp_pcb
*pcb
)
1074 TCP_RMV(pcblist
, pcb
);
1078 /* if there is an outstanding delayed ACKs, send it */
1079 if (pcb
->state
!= TIME_WAIT
&&
1080 pcb
->state
!= LISTEN
&&
1081 pcb
->flags
& TF_ACK_DELAY
) {
1082 pcb
->flags
|= TF_ACK_NOW
;
1085 pcb
->state
= CLOSED
;
1087 LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane());
1093 * Calculates a new initial sequence number for new connections.
1100 static u32_t iss
= 6510;
1102 iss
+= tcp_ticks
; /* XXX */
1106 #endif /* LWIP_TCP */