Mistake on this page?
Report an issue in GitHub or email us
tcp_priv.h
Go to the documentation of this file.
1 /**
2  * @file
3  * TCP internal implementations (do not use in application code)
4  */
5 
6 /*
7  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without modification,
11  * are permitted provided that the following conditions are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright notice,
14  * this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  * 3. The name of the author may not be used to endorse or promote products
19  * derived from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
22  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
24  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
29  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
30  * OF SUCH DAMAGE.
31  *
32  * This file is part of the lwIP TCP/IP stack.
33  *
34  * Author: Adam Dunkels <adam@sics.se>
35  *
36  */
37 #ifndef LWIP_HDR_TCP_PRIV_H
38 #define LWIP_HDR_TCP_PRIV_H
39 
40 #include "lwip/opt.h"
41 
42 #if LWIP_TCP /* don't build if not configured for use in lwipopts.h */
43 
44 #include "lwip/tcp.h"
45 #include "lwip/mem.h"
46 #include "lwip/pbuf.h"
47 #include "lwip/ip.h"
48 #include "lwip/icmp.h"
49 #include "lwip/err.h"
50 #include "lwip/ip6.h"
51 #include "lwip/ip6_addr.h"
52 #include "lwip/prot/tcp.h"
53 
54 #ifdef __cplusplus
55 extern "C" {
56 #endif
57 
58 /* Functions for interfacing with TCP: */
59 
60 /* Lower layer interface to TCP: */
61 void tcp_init (void); /* Initialize this module. */
62 void tcp_tmr (void); /* Must be called every
63  TCP_TMR_INTERVAL
64  ms. (Typically 250 ms). */
65 /* It is also possible to call these two functions at the right
66  intervals (instead of calling tcp_tmr()). */
67 void tcp_slowtmr (void);
68 void tcp_fasttmr (void);
69 
70 /* Call this from a netif driver (watch out for threading issues!) that has
71  returned a memory error on transmit and now has free buffers to send more.
72  This iterates all active pcbs that had an error and tries to call
73  tcp_output, so use this with care as it might slow down the system. */
74 void tcp_txnow (void);
75 
76 /* Only used by IP to pass a TCP segment to TCP: */
77 void tcp_input (struct pbuf *p, struct netif *inp);
78 /* Used within the TCP code only: */
79 struct tcp_pcb * tcp_alloc (u8_t prio);
80 void tcp_free (struct tcp_pcb *pcb);
81 void tcp_abandon (struct tcp_pcb *pcb, int reset);
82 err_t tcp_send_empty_ack(struct tcp_pcb *pcb);
83 err_t tcp_rexmit (struct tcp_pcb *pcb);
84 err_t tcp_rexmit_rto_prepare(struct tcp_pcb *pcb);
85 void tcp_rexmit_rto_commit(struct tcp_pcb *pcb);
86 void tcp_rexmit_rto (struct tcp_pcb *pcb);
87 void tcp_rexmit_fast (struct tcp_pcb *pcb);
88 u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb);
89 err_t tcp_process_refused_data(struct tcp_pcb *pcb);
90 
91 /**
92  * This is the Nagle algorithm: try to combine user data to send as few TCP
93  * segments as possible. Only send if
94  * - no previously transmitted data on the connection remains unacknowledged or
95  * - the TF_NODELAY flag is set (nagle algorithm turned off for this pcb) or
96  * - the only unsent segment is at least pcb->mss bytes long (or there is more
97  * than one unsent segment - with lwIP, this can happen although unsent->len < mss)
98  * - or if we are in fast-retransmit (TF_INFR)
99  */
100 #define tcp_do_output_nagle(tpcb) ((((tpcb)->unacked == NULL) || \
101  ((tpcb)->flags & (TF_NODELAY | TF_INFR)) || \
102  (((tpcb)->unsent != NULL) && (((tpcb)->unsent->next != NULL) || \
103  ((tpcb)->unsent->len >= (tpcb)->mss))) || \
104  ((tcp_sndbuf(tpcb) == 0) || (tcp_sndqueuelen(tpcb) >= TCP_SND_QUEUELEN)) \
105  ) ? 1 : 0)
106 #define tcp_output_nagle(tpcb) (tcp_do_output_nagle(tpcb) ? tcp_output(tpcb) : ERR_OK)
107 
108 
109 #define TCP_SEQ_LT(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) < 0)
110 #define TCP_SEQ_LEQ(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) <= 0)
111 #define TCP_SEQ_GT(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) > 0)
112 #define TCP_SEQ_GEQ(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) >= 0)
113 /* is b<=a<=c? */
114 #if 0 /* see bug #10548 */
115 #define TCP_SEQ_BETWEEN(a,b,c) ((c)-(b) >= (a)-(b))
116 #endif
117 #define TCP_SEQ_BETWEEN(a,b,c) (TCP_SEQ_GEQ(a,b) && TCP_SEQ_LEQ(a,c))
118 
119 #ifndef TCP_TMR_INTERVAL
120 #define TCP_TMR_INTERVAL 250 /* The TCP timer interval in milliseconds. */
121 #endif /* TCP_TMR_INTERVAL */
122 
123 #ifndef TCP_FAST_INTERVAL
124 #define TCP_FAST_INTERVAL TCP_TMR_INTERVAL /* the fine grained timeout in milliseconds */
125 #endif /* TCP_FAST_INTERVAL */
126 
127 #ifndef TCP_SLOW_INTERVAL
128 #define TCP_SLOW_INTERVAL (2*TCP_TMR_INTERVAL) /* the coarse grained timeout in milliseconds */
129 #endif /* TCP_SLOW_INTERVAL */
130 
131 #define TCP_FIN_WAIT_TIMEOUT 20000 /* milliseconds */
132 #define TCP_SYN_RCVD_TIMEOUT 20000 /* milliseconds */
133 
134 #define TCP_OOSEQ_TIMEOUT 6U /* x RTO */
135 
136 #ifndef TCP_MSL
137 #define TCP_MSL 60000UL /* The maximum segment lifetime in milliseconds */
138 #endif
139 
140 /* Keepalive values, compliant with RFC 1122. Don't change this unless you know what you're doing */
141 #ifndef TCP_KEEPIDLE_DEFAULT
142 #define TCP_KEEPIDLE_DEFAULT 7200000UL /* Default KEEPALIVE timer in milliseconds */
143 #endif
144 
145 #ifndef TCP_KEEPINTVL_DEFAULT
146 #define TCP_KEEPINTVL_DEFAULT 75000UL /* Default Time between KEEPALIVE probes in milliseconds */
147 #endif
148 
149 #ifndef TCP_KEEPCNT_DEFAULT
150 #define TCP_KEEPCNT_DEFAULT 9U /* Default Counter for KEEPALIVE probes */
151 #endif
152 
153 #define TCP_MAXIDLE TCP_KEEPCNT_DEFAULT * TCP_KEEPINTVL_DEFAULT /* Maximum KEEPALIVE probe time */
154 
155 #define TCP_TCPLEN(seg) ((seg)->len + (((TCPH_FLAGS((seg)->tcphdr) & (TCP_FIN | TCP_SYN)) != 0) ? 1U : 0U))
156 
157 /** Flags used on input processing, not on pcb->flags
158 */
159 #define TF_RESET (u8_t)0x08U /* Connection was reset. */
160 #define TF_CLOSED (u8_t)0x10U /* Connection was successfully closed. */
161 #define TF_GOT_FIN (u8_t)0x20U /* Connection was closed by the remote end. */
162 
163 
164 #if LWIP_EVENT_API
165 
166 #define TCP_EVENT_ACCEPT(lpcb,pcb,arg,err,ret) ret = lwip_tcp_event(arg, (pcb),\
167  LWIP_EVENT_ACCEPT, NULL, 0, err)
168 #define TCP_EVENT_SENT(pcb,space,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
169  LWIP_EVENT_SENT, NULL, space, ERR_OK)
170 #define TCP_EVENT_RECV(pcb,p,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
171  LWIP_EVENT_RECV, (p), 0, (err))
172 #define TCP_EVENT_CLOSED(pcb,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
173  LWIP_EVENT_RECV, NULL, 0, ERR_OK)
174 #define TCP_EVENT_CONNECTED(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
175  LWIP_EVENT_CONNECTED, NULL, 0, (err))
176 #define TCP_EVENT_POLL(pcb,ret) do { if ((pcb)->state != SYN_RCVD) { \
177  ret = lwip_tcp_event((pcb)->callback_arg, (pcb), LWIP_EVENT_POLL, NULL, 0, ERR_OK); \
178  } else { \
179  ret = ERR_ARG; } } while(0)
180 /* For event API, last state SYN_RCVD must be excluded here: the application
181  has not seen this pcb, yet! */
182 #define TCP_EVENT_ERR(last_state,errf,arg,err) do { if (last_state != SYN_RCVD) { \
183  lwip_tcp_event((arg), NULL, LWIP_EVENT_ERR, NULL, 0, (err)); } } while(0)
184 
185 #else /* LWIP_EVENT_API */
186 
187 #define TCP_EVENT_ACCEPT(lpcb,pcb,arg,err,ret) \
188  do { \
189  if((lpcb)->accept != NULL) \
190  (ret) = (lpcb)->accept((arg),(pcb),(err)); \
191  else (ret) = ERR_ARG; \
192  } while (0)
193 
194 #define TCP_EVENT_SENT(pcb,space,ret) \
195  do { \
196  if((pcb)->sent != NULL) \
197  (ret) = (pcb)->sent((pcb)->callback_arg,(pcb),(space)); \
198  else (ret) = ERR_OK; \
199  } while (0)
200 
201 #define TCP_EVENT_RECV(pcb,p,err,ret) \
202  do { \
203  if((pcb)->recv != NULL) { \
204  (ret) = (pcb)->recv((pcb)->callback_arg,(pcb),(p),(err));\
205  } else { \
206  (ret) = tcp_recv_null(NULL, (pcb), (p), (err)); \
207  } \
208  } while (0)
209 
210 #define TCP_EVENT_CLOSED(pcb,ret) \
211  do { \
212  if(((pcb)->recv != NULL)) { \
213  (ret) = (pcb)->recv((pcb)->callback_arg,(pcb),NULL,ERR_OK);\
214  } else { \
215  (ret) = ERR_OK; \
216  } \
217  } while (0)
218 
219 #define TCP_EVENT_CONNECTED(pcb,err,ret) \
220  do { \
221  if((pcb)->connected != NULL) \
222  (ret) = (pcb)->connected((pcb)->callback_arg,(pcb),(err)); \
223  else (ret) = ERR_OK; \
224  } while (0)
225 
226 #define TCP_EVENT_POLL(pcb,ret) \
227  do { \
228  if((pcb)->poll != NULL) \
229  (ret) = (pcb)->poll((pcb)->callback_arg,(pcb)); \
230  else (ret) = ERR_OK; \
231  } while (0)
232 
233 #define TCP_EVENT_ERR(last_state,errf,arg,err) \
234  do { \
235  LWIP_UNUSED_ARG(last_state); \
236  if((errf) != NULL) \
237  (errf)((arg),(err)); \
238  } while (0)
239 
240 #endif /* LWIP_EVENT_API */
241 
242 /** Enabled extra-check for TCP_OVERSIZE if LWIP_DEBUG is enabled */
243 #if TCP_OVERSIZE && defined(LWIP_DEBUG)
244 #define TCP_OVERSIZE_DBGCHECK 1
245 #else
246 #define TCP_OVERSIZE_DBGCHECK 0
247 #endif
248 
249 /** Don't generate checksum on copy if CHECKSUM_GEN_TCP is disabled */
250 #define TCP_CHECKSUM_ON_COPY (LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_TCP)
251 
252 /* This structure represents a TCP segment on the unsent, unacked and ooseq queues */
253 struct tcp_seg {
254  struct tcp_seg *next; /* used when putting segments on a queue */
255  struct pbuf *p; /* buffer containing data + TCP header */
256  u16_t len; /* the TCP length of this segment */
257 #if TCP_OVERSIZE_DBGCHECK
258  u16_t oversize_left; /* Extra bytes available at the end of the last
259  pbuf in unsent (used for asserting vs.
260  tcp_pcb.unsent_oversize only) */
261 #endif /* TCP_OVERSIZE_DBGCHECK */
262 #if TCP_CHECKSUM_ON_COPY
263  u16_t chksum;
264  u8_t chksum_swapped;
265 #endif /* TCP_CHECKSUM_ON_COPY */
266  u8_t flags;
267 #define TF_SEG_OPTS_MSS (u8_t)0x01U /* Include MSS option (only used in SYN segments) */
268 #define TF_SEG_OPTS_TS (u8_t)0x02U /* Include timestamp option. */
269 #define TF_SEG_DATA_CHECKSUMMED (u8_t)0x04U /* ALL data (not the header) is
270  checksummed into 'chksum' */
271 #define TF_SEG_OPTS_WND_SCALE (u8_t)0x08U /* Include WND SCALE option (only used in SYN segments) */
272 #define TF_SEG_OPTS_SACK_PERM (u8_t)0x10U /* Include SACK Permitted option (only used in SYN segments) */
273  struct tcp_hdr *tcphdr; /* the TCP header */
274 };
275 
276 #define LWIP_TCP_OPT_EOL 0
277 #define LWIP_TCP_OPT_NOP 1
278 #define LWIP_TCP_OPT_MSS 2
279 #define LWIP_TCP_OPT_WS 3
280 #define LWIP_TCP_OPT_SACK_PERM 4
281 #define LWIP_TCP_OPT_TS 8
282 
283 #define LWIP_TCP_OPT_LEN_MSS 4
284 #if LWIP_TCP_TIMESTAMPS
285 #define LWIP_TCP_OPT_LEN_TS 10
286 #define LWIP_TCP_OPT_LEN_TS_OUT 12 /* aligned for output (includes NOP padding) */
287 #else
288 #define LWIP_TCP_OPT_LEN_TS_OUT 0
289 #endif
290 #if LWIP_WND_SCALE
291 #define LWIP_TCP_OPT_LEN_WS 3
292 #define LWIP_TCP_OPT_LEN_WS_OUT 4 /* aligned for output (includes NOP padding) */
293 #else
294 #define LWIP_TCP_OPT_LEN_WS_OUT 0
295 #endif
296 
297 #if LWIP_TCP_SACK_OUT
298 #define LWIP_TCP_OPT_LEN_SACK_PERM 2
299 #define LWIP_TCP_OPT_LEN_SACK_PERM_OUT 4 /* aligned for output (includes NOP padding) */
300 #else
301 #define LWIP_TCP_OPT_LEN_SACK_PERM_OUT 0
302 #endif
303 
304 #define LWIP_TCP_OPT_LENGTH(flags) \
305  ((flags) & TF_SEG_OPTS_MSS ? LWIP_TCP_OPT_LEN_MSS : 0) + \
306  ((flags) & TF_SEG_OPTS_TS ? LWIP_TCP_OPT_LEN_TS_OUT : 0) + \
307  ((flags) & TF_SEG_OPTS_WND_SCALE ? LWIP_TCP_OPT_LEN_WS_OUT : 0) + \
308  ((flags) & TF_SEG_OPTS_SACK_PERM ? LWIP_TCP_OPT_LEN_SACK_PERM_OUT : 0)
309 
310 /** This returns a TCP header option for MSS in an u32_t */
311 #define TCP_BUILD_MSS_OPTION(mss) lwip_htonl(0x02040000 | ((mss) & 0xFFFF))
312 
313 #if LWIP_WND_SCALE
314 #define TCPWNDSIZE_F U32_F
315 #define TCPWND_MAX 0xFFFFFFFFU
316 #define TCPWND_CHECK16(x) LWIP_ASSERT("window size > 0xFFFF", (x) <= 0xFFFF)
317 #define TCPWND_MIN16(x) ((u16_t)LWIP_MIN((x), 0xFFFF))
318 #else /* LWIP_WND_SCALE */
319 #define TCPWNDSIZE_F U16_F
320 #define TCPWND_MAX 0xFFFFU
321 #define TCPWND_CHECK16(x)
322 #define TCPWND_MIN16(x) x
323 #endif /* LWIP_WND_SCALE */
324 
325 /* Global variables: */
326 extern struct tcp_pcb *tcp_input_pcb;
327 extern u32_t tcp_ticks;
328 extern u8_t tcp_active_pcbs_changed;
329 
330 /* The TCP PCB lists. */
331 union tcp_listen_pcbs_t { /* List of all TCP PCBs in LISTEN state. */
332  struct tcp_pcb_listen *listen_pcbs;
333  struct tcp_pcb *pcbs;
334 };
335 extern struct tcp_pcb *tcp_bound_pcbs;
336 extern union tcp_listen_pcbs_t tcp_listen_pcbs;
337 extern struct tcp_pcb *tcp_active_pcbs; /* List of all TCP PCBs that are in a
338  state in which they accept or send
339  data. */
340 extern struct tcp_pcb *tcp_tw_pcbs; /* List of all TCP PCBs in TIME-WAIT. */
341 
342 #define NUM_TCP_PCB_LISTS_NO_TIME_WAIT 3
343 #define NUM_TCP_PCB_LISTS 4
344 extern struct tcp_pcb ** const tcp_pcb_lists[NUM_TCP_PCB_LISTS];
345 
346 /* Axioms about the above lists:
347  1) Every TCP PCB that is not CLOSED is in one of the lists.
348  2) A PCB is only in one of the lists.
349  3) All PCBs in the tcp_listen_pcbs list is in LISTEN state.
350  4) All PCBs in the tcp_tw_pcbs list is in TIME-WAIT state.
351 */
352 /* Define two macros, TCP_REG and TCP_RMV that registers a TCP PCB
353  with a PCB list or removes a PCB from a list, respectively. */
354 #ifndef TCP_DEBUG_PCB_LISTS
355 #define TCP_DEBUG_PCB_LISTS 0
356 #endif
357 #if TCP_DEBUG_PCB_LISTS
358 #define TCP_REG(pcbs, npcb) do {\
359  struct tcp_pcb *tcp_tmp_pcb; \
360  LWIP_DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %"U16_F"\n", (void *)(npcb), (npcb)->local_port)); \
361  for (tcp_tmp_pcb = *(pcbs); \
362  tcp_tmp_pcb != NULL; \
363  tcp_tmp_pcb = tcp_tmp_pcb->next) { \
364  LWIP_ASSERT("TCP_REG: already registered\n", tcp_tmp_pcb != (npcb)); \
365  } \
366  LWIP_ASSERT("TCP_REG: pcb->state != CLOSED", ((pcbs) == &tcp_bound_pcbs) || ((npcb)->state != CLOSED)); \
367  (npcb)->next = *(pcbs); \
368  LWIP_ASSERT("TCP_REG: npcb->next != npcb", (npcb)->next != (npcb)); \
369  *(pcbs) = (npcb); \
370  LWIP_ASSERT("TCP_REG: tcp_pcbs sane", tcp_pcbs_sane()); \
371  tcp_timer_needed(); \
372  } while(0)
373 #define TCP_RMV(pcbs, npcb) do { \
374  struct tcp_pcb *tcp_tmp_pcb; \
375  LWIP_ASSERT("TCP_RMV: pcbs != NULL", *(pcbs) != NULL); \
376  LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removing %p from %p\n", (void *)(npcb), (void *)(*(pcbs)))); \
377  if(*(pcbs) == (npcb)) { \
378  *(pcbs) = (*pcbs)->next; \
379  } else for (tcp_tmp_pcb = *(pcbs); tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \
380  if(tcp_tmp_pcb->next == (npcb)) { \
381  tcp_tmp_pcb->next = (npcb)->next; \
382  break; \
383  } \
384  } \
385  (npcb)->next = NULL; \
386  LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \
387  LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", (void *)(npcb), (void *)(*(pcbs)))); \
388  } while(0)
389 
390 #else /* LWIP_DEBUG */
391 
392 #define TCP_REG(pcbs, npcb) \
393  do { \
394  (npcb)->next = *pcbs; \
395  *(pcbs) = (npcb); \
396  tcp_timer_needed(); \
397  } while (0)
398 
399 #define TCP_RMV(pcbs, npcb) \
400  do { \
401  if(*(pcbs) == (npcb)) { \
402  (*(pcbs)) = (*pcbs)->next; \
403  } \
404  else { \
405  struct tcp_pcb *tcp_tmp_pcb; \
406  for (tcp_tmp_pcb = *pcbs; \
407  tcp_tmp_pcb != NULL; \
408  tcp_tmp_pcb = tcp_tmp_pcb->next) { \
409  if(tcp_tmp_pcb->next == (npcb)) { \
410  tcp_tmp_pcb->next = (npcb)->next; \
411  break; \
412  } \
413  } \
414  } \
415  (npcb)->next = NULL; \
416  } while(0)
417 
418 #endif /* LWIP_DEBUG */
419 
420 #define TCP_REG_ACTIVE(npcb) \
421  do { \
422  TCP_REG(&tcp_active_pcbs, npcb); \
423  tcp_active_pcbs_changed = 1; \
424  } while (0)
425 
426 #define TCP_RMV_ACTIVE(npcb) \
427  do { \
428  TCP_RMV(&tcp_active_pcbs, npcb); \
429  tcp_active_pcbs_changed = 1; \
430  } while (0)
431 
432 #define TCP_PCB_REMOVE_ACTIVE(pcb) \
433  do { \
434  tcp_pcb_remove(&tcp_active_pcbs, pcb); \
435  tcp_active_pcbs_changed = 1; \
436  } while (0)
437 
438 
439 /* Internal functions: */
440 struct tcp_pcb *tcp_pcb_copy(struct tcp_pcb *pcb);
441 void tcp_pcb_purge(struct tcp_pcb *pcb);
442 void tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb);
443 
444 void tcp_segs_free(struct tcp_seg *seg);
445 void tcp_seg_free(struct tcp_seg *seg);
446 struct tcp_seg *tcp_seg_copy(struct tcp_seg *seg);
447 
448 #define tcp_ack(pcb) \
449  do { \
450  if((pcb)->flags & TF_ACK_DELAY) { \
451  tcp_clear_flags(pcb, TF_ACK_DELAY); \
452  tcp_ack_now(pcb); \
453  } \
454  else { \
455  tcp_set_flags(pcb, TF_ACK_DELAY); \
456  } \
457  } while (0)
458 
459 #define tcp_ack_now(pcb) \
460  tcp_set_flags(pcb, TF_ACK_NOW)
461 
462 err_t tcp_send_fin(struct tcp_pcb *pcb);
463 err_t tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags);
464 
465 void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg);
466 
467 void tcp_rst(const struct tcp_pcb* pcb, u32_t seqno, u32_t ackno,
468  const ip_addr_t *local_ip, const ip_addr_t *remote_ip,
469  u16_t local_port, u16_t remote_port);
470 
471 u32_t tcp_next_iss(struct tcp_pcb *pcb);
472 
473 err_t tcp_keepalive(struct tcp_pcb *pcb);
474 err_t tcp_split_unsent_seg(struct tcp_pcb *pcb, u16_t split);
475 err_t tcp_zero_window_probe(struct tcp_pcb *pcb);
476 void tcp_trigger_input_pcb_close(void);
477 
478 #if TCP_CALCULATE_EFF_SEND_MSS
479 u16_t tcp_eff_send_mss_netif(u16_t sendmss, struct netif *outif,
480  const ip_addr_t *dest);
481 #define tcp_eff_send_mss(sendmss, src, dest) \
482  tcp_eff_send_mss_netif(sendmss, ip_route(src, dest), dest)
483 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
484 
485 #if LWIP_CALLBACK_API
486 err_t tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);
487 #endif /* LWIP_CALLBACK_API */
488 
489 #if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG
490 void tcp_debug_print(struct tcp_hdr *tcphdr);
491 void tcp_debug_print_flags(u8_t flags);
492 void tcp_debug_print_state(enum tcp_state s);
493 void tcp_debug_print_pcbs(void);
494 s16_t tcp_pcbs_sane(void);
495 #else
496 # define tcp_debug_print(tcphdr)
497 # define tcp_debug_print_flags(flags)
498 # define tcp_debug_print_state(s)
499 # define tcp_debug_print_pcbs()
500 # define tcp_pcbs_sane() 1
501 #endif /* TCP_DEBUG */
502 
503 /** External function (implemented in timers.c), called when TCP detects
504  * that a timer is needed (i.e. active- or time-wait-pcb found). */
505 void tcp_timer_needed(void);
506 
507 void tcp_netif_ip_addr_changed(const ip_addr_t* old_addr, const ip_addr_t* new_addr);
508 
509 #if TCP_QUEUE_OOSEQ
510 void tcp_free_ooseq(struct tcp_pcb *pcb);
511 #endif
512 
513 #if LWIP_TCP_PCB_NUM_EXT_ARGS
514 err_t tcp_ext_arg_invoke_callbacks_passive_open(struct tcp_pcb_listen *lpcb, struct tcp_pcb *cpcb);
515 #endif
516 
517 #ifdef __cplusplus
518 }
519 #endif
520 
521 #endif /* LWIP_TCP */
522 
523 #endif /* LWIP_HDR_TCP_PRIV_H */
Heap API.
IPv6 layer.
IP API.
lwIP Options Configuration
IPv6 addresses.
u8_t flags
misc flags
Definition: pbuf.h:211
TCP protocol definitions.
Main packet buffer struct.
lwIP Error codes
Generic data structure used for all lwIP network interfaces.
pbuf API
IP address structure for passing IP addresses by value.
Definition: nsapi_types.h:235
ICMP API.
TCP API (to be used from TCPIP thread) See also tcp_raw.
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.