1 /** 2 * @file 3 * TCP API (to be used from TCPIP thread)\n 4 * See also @ref tcp_raw 5 */ 6 7 /* 8 * Copyright (c) 2001-2004 Swedish Institute of Computer Science. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without modification, 12 * are permitted provided that the following conditions are met: 13 * 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. 21 * 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 31 * OF SUCH DAMAGE. 32 * 33 * This file is part of the lwIP TCP/IP stack. 34 * 35 * Author: Adam Dunkels <adam@sics.se> 36 * 37 */ 38 #ifndef LWIP_HDR_TCP_H 39 #define LWIP_HDR_TCP_H 40 41 #include "lwip/opt.h" 42 43 #if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ 44 45 #include "lwip/tcpbase.h" 46 #include "lwip/mem.h" 47 #include "lwip/pbuf.h" 48 #include "lwip/ip.h" 49 #include "lwip/icmp.h" 50 #include "lwip/err.h" 51 #include "lwip/ip6.h" 52 #include "lwip/ip6_addr.h" 53 54 #ifdef __cplusplus 55 extern "C" { 56 #endif 57 58 #define TCP_SND_QUEUELEN_LOWAT_THRES 5 59 60 struct tcp_pcb; 61 struct tcp_pcb_listen; 62 63 /** Function prototype for tcp accept callback functions. Called when a new 64 * connection can be accepted on a listening pcb. 65 * 66 * @param arg Additional argument to pass to the callback function (@see tcp_arg()) 67 * @param newpcb The new connection pcb 68 * @param err An error code if there has been an error accepting. 69 * Only return ERR_ABRT if you have called tcp_abort from within the 70 * callback function! 71 */ 72 typedef err_t (*tcp_accept_fn)(void *arg, struct tcp_pcb *newpcb, err_t err); 73 74 /** Function prototype for tcp receive callback functions. Called when data has 75 * been received. 76 * 77 * @param arg Additional argument to pass to the callback function (@see tcp_arg()) 78 * @param tpcb The connection pcb which received data 79 * @param p The received data (or NULL when the connection has been closed!) 80 * @param err An error code if there has been an error receiving 81 * Only return ERR_ABRT if you have called tcp_abort from within the 82 * callback function! 83 */ 84 typedef err_t (*tcp_recv_fn)(void *arg, struct tcp_pcb *tpcb, 85 struct pbuf *p, err_t err); 86 87 /** Function prototype for tcp sent callback functions. Called when sent data has 88 * been acknowledged by the remote side. Use it to free corresponding resources. 89 * This also means that the pcb has now space available to send new data. 90 * 91 * @param arg Additional argument to pass to the callback function (@see tcp_arg()) 92 * @param tpcb The connection pcb for which data has been acknowledged 93 * @param len The amount of bytes acknowledged 94 * @return ERR_OK: try to send some data by calling tcp_output 95 * Only return ERR_ABRT if you have called tcp_abort from within the 96 * callback function! 97 */ 98 typedef err_t (*tcp_sent_fn)(void *arg, struct tcp_pcb *tpcb, 99 u16_t len); 100 101 /** Function prototype for tcp poll callback functions. Called periodically as 102 * specified by @see tcp_poll. 103 * 104 * @param arg Additional argument to pass to the callback function (@see tcp_arg()) 105 * @param tpcb tcp pcb 106 * @return ERR_OK: try to send some data by calling tcp_output 107 * Only return ERR_ABRT if you have called tcp_abort from within the 108 * callback function! 109 */ 110 typedef err_t (*tcp_poll_fn)(void *arg, struct tcp_pcb *tpcb); 111 112 /** Function prototype for tcp error callback functions. Called when the pcb 113 * receives a RST or is unexpectedly closed for any other reason. 114 * 115 * @note The corresponding pcb is already freed when this callback is called! 116 * 117 * @param arg Additional argument to pass to the callback function (@see tcp_arg()) 118 * @param err Error code to indicate why the pcb has been closed 119 * ERR_ABRT: aborted through tcp_abort or by a TCP timer 120 * ERR_RST: the connection was reset by the remote host 121 */ 122 typedef void (*tcp_err_fn)(void *arg, err_t err); 123 124 /** Function prototype for tcp connected callback functions. Called when a pcb 125 * is connected to the remote side after initiating a connection attempt by 126 * calling tcp_connect(). 127 * 128 * @param arg Additional argument to pass to the callback function (@see tcp_arg()) 129 * @param tpcb The connection pcb which is connected 130 * @param err An unused error code, always ERR_OK currently ;-) @todo! 131 * Only return ERR_ABRT if you have called tcp_abort from within the 132 * callback function! 133 * 134 * @note When a connection attempt fails, the error callback is currently called! 135 */ 136 typedef err_t (*tcp_connected_fn)(void *arg, struct tcp_pcb *tpcb, err_t err); 137 138 #if DRIVER_STATUS_CHECK 139 typedef void (*tcp_event_sndplus_fn)(void *arg, const struct tcp_pcb *tpcb); 140 #endif 141 142 #if LWIP_WND_SCALE 143 #define RCV_WND_SCALE(pcb, wnd) (((wnd) >> (pcb)->rcv_scale)) 144 #define SND_WND_SCALE(pcb, wnd) (((tcpwnd_size_t)(wnd) << (pcb)->snd_scale)) 145 #define TCPWND16(x) ((u16_t)LWIP_MIN((x), 0xFFFF)) 146 #define TCP_WND_MAX(pcb) ((tcpwnd_size_t)(((pcb)->flags & TF_WND_SCALE) ? TCP_WND : TCPWND16(TCP_WND))) 147 #else 148 #define RCV_WND_SCALE(pcb, wnd) (wnd) 149 #define SND_WND_SCALE(pcb, wnd) (wnd) 150 #define TCPWND16(x) (x) 151 #define TCP_WND_MAX(pcb) TCP_WND 152 #endif 153 /* Increments a tcpwnd_size_t and holds at max value rather than rollover */ 154 #define TCP_WND_INC(wnd, inc) do { \ 155 if ((tcpwnd_size_t)((wnd) + (inc)) >= (wnd)) { \ 156 (wnd) = (tcpwnd_size_t)((wnd) + (inc)); \ 157 } else { \ 158 (wnd) = (tcpwnd_size_t) - 1; \ 159 } \ 160 } while (0) 161 162 #define TCP_WND_DEC(wnd, dec, mss) do { \ 163 if ((wnd) >= (dec) && (wnd) >= (mss)) { \ 164 (wnd) = (tcpwnd_size_t)(wnd - (dec)); \ 165 } else { \ 166 (wnd) = (mss); \ 167 } \ 168 } while (0) 169 170 #ifndef LWIP_INITIAL_CWND_OVERRIDE 171 /* 172 [RFC 5681] [3.1. Slow Start and Congestion Avoidance] 173 IW, the initial value of cwnd, MUST be set using the following guidelines as an upper bound. 174 */ 175 #define LWIP_TCP_CALC_INITIAL_CWND(SMSS, IW) do { \ 176 if ((SMSS) > 2190){ \ 177 IW = (tcpwnd_size_t)(2 * LWIP_MIN(SMSS, TCP_MAX_MSS)); \ 178 } else if (((SMSS) > 1095) && ((SMSS) <= 2190)) { \ 179 IW = (tcpwnd_size_t)(3 * LWIP_MIN(SMSS, TCP_MAX_MSS)); \ 180 } else if ((SMSS) <= 1095) { \ 181 IW = (tcpwnd_size_t)(4 * LWIP_MIN(SMSS, TCP_MAX_MSS)); \ 182 } \ 183 } while (0) 184 #else 185 #define LWIP_TCP_CALC_INITIAL_CWND(SMSS, IW) do { \ 186 IW = (tcpwnd_size_t)(LWIP_INITIAL_CWND_OVERRIDE * (SMSS)); \ 187 } while (0) 188 #endif 189 190 /* Increments a wnd * mss and holds at max value rather than rollover */ 191 #define TCP_CALC_SSTHRESH(pcb, ssthresh, wnd, mss) do { \ 192 if (((u64_t)(wnd) * (mss)) < TCP_WND_MAX(pcb)) { \ 193 (ssthresh) = (tcpwnd_size_t)((wnd) * (mss)); \ 194 } else { \ 195 (ssthresh) = TCP_WND_MAX(pcb); \ 196 } \ 197 } while (0) 198 199 #ifndef LWIP_CONGCNTRL_DUPACK_THRESH 200 /** Congestion Control duplicate Acknowledgement Threshold */ 201 #define DUPACK_THRESH 3 202 #else 203 #define DUPACK_THRESH LWIP_CONGCNTRL_DUPACK_THRESH 204 #endif 205 206 /** Initial Congestion Control Window (by MSS). */ 207 #define INITIAL_CWND 4U 208 209 #ifndef LWIP_CONGCNTRL_INITIAL_SSTHRESH 210 /** Initial Congestion Control Slow Start Threshold. */ 211 #define INITIAL_SSTHRESH 40 212 #else 213 #define INITIAL_SSTHRESH LWIP_CONGCNTRL_INITIAL_SSTHRESH 214 #endif 215 216 #if DRIVER_STATUS_CHECK 217 #define DRV_READY 1 218 #define DRV_NOT_READY 0 219 #endif 220 221 /* Indicates that this pbuf includes a TCP FIN flag and post to mbox is failed */ 222 #define TCP_PBUF_FLAG_TCP_FIN_RECV_SYSPOST_FAIL 0x01U 223 224 /* Adding for SACK */ 225 #if LWIP_SACK 226 struct _sack_seq { 227 struct _sack_seq *next; 228 u32_t left; 229 u32_t right; 230 u32_t order; 231 }; 232 #endif 233 234 #if LWIP_SACK_PERF_OPT 235 struct tcp_sack_fast_rxmited { 236 struct tcp_sack_fast_rxmited *next; 237 struct tcp_seg *seg; 238 }; 239 #endif 240 241 /** Function prototype for deallocation of arguments. Called *just before* the 242 * pcb is freed, so don't expect to be able to do anything with this pcb! 243 * 244 * @param id ext arg id (allocated via @ref tcp_ext_arg_alloc_id) 245 * @param data pointer to the data (set via @ref tcp_ext_arg_set before) 246 */ 247 typedef void (*tcp_extarg_callback_pcb_destroyed_fn)(u8_t id, void *data); 248 249 /** Function prototype to transition arguments from a listening pcb to an accepted pcb 250 * 251 * @param id ext arg id (allocated via @ref tcp_ext_arg_alloc_id) 252 * @param lpcb the listening pcb accepting a connection 253 * @param cpcb the newly allocated connection pcb 254 * @return ERR_OK if OK, any error if connection should be dropped 255 */ 256 typedef err_t (*tcp_extarg_callback_passive_open_fn)(u8_t id, struct tcp_pcb_listen *lpcb, struct tcp_pcb *cpcb); 257 258 /** A table of callback functions that is invoked for ext arguments */ 259 struct tcp_ext_arg_callbacks { 260 /** @ref tcp_extarg_callback_pcb_destroyed_fn */ 261 tcp_extarg_callback_pcb_destroyed_fn destroy; 262 /** @ref tcp_extarg_callback_passive_open_fn */ 263 tcp_extarg_callback_passive_open_fn passive_open; 264 }; 265 266 #define LWIP_TCP_PCB_NUM_EXT_ARG_ID_INVALID 0xFF 267 268 #if LWIP_SO_SNDBUF 269 #define LWIP_SO_SNDBUF_DECL u32_t snd_buf_static; 270 #else 271 #define LWIP_SO_SNDBUF_DECL 272 #endif /* LWIP_SO_SNDBUF */ 273 274 #if LWIP_TCP_MAXSEG 275 #define LWIP_TCP_MAXSEG_DECL u16_t usr_mss; 276 #else 277 #define LWIP_TCP_MAXSEG_DECL 278 #endif /* LWIP_TCP_MAXSEG */ 279 280 #if LWIP_TCP_PCB_NUM_EXT_ARGS 281 /* This is the structure for ext args in tcp pcbs (used as array) */ 282 struct tcp_pcb_ext_args { 283 const struct tcp_ext_arg_callbacks *callbacks; 284 void *data; 285 }; 286 /* This is a helper define to prevent zero size arrays if disabled */ 287 #define TCP_PCB_EXTARGS struct tcp_pcb_ext_args ext_args[LWIP_TCP_PCB_NUM_EXT_ARGS]; 288 #else 289 #define TCP_PCB_EXTARGS 290 #endif 291 292 typedef u32_t tcpflags_t; 293 #define TCP_ALLFLAGS 0xFFFFFFFFU 294 295 296 /** 297 * members common to struct tcp_pcb and struct tcp_listen_pcb 298 */ 299 #define TCP_PCB_COMMON(type) \ 300 type *next; /* for the linked list */ \ 301 void *callback_arg; \ 302 TCP_PCB_EXTARGS \ 303 enum tcp_state state; /* TCP state */ \ 304 u8_t prio; \ 305 /* ports are in host byte order */ \ 306 u16_t local_port; \ 307 /* user mss set by TCP_MAXSEG option */ \ 308 LWIP_TCP_MAXSEG_DECL \ 309 /* Configured send buffer size */ \ 310 LWIP_SO_SNDBUF_DECL 311 312 #if LWIP_TCP_TLP_SUPPORT 313 314 #define TCP_TLP_MAX_PROBE_CNT 2 315 316 #define LWIP_TCP_TLP_CLEAR_VARS(_pcb) do { \ 317 _pcb->tlp_pto_cnt = 0; \ 318 _pcb->tlp_rtx_out = 0; \ 319 _pcb->tlp_high_rxt = 0; \ 320 _pcb->tlp_time_stamp = 0; \ 321 } while (0) 322 323 #define LWIP_TCP_TLP_WCDELACKT 200 /* RECOMMENDED value is 200ms */ 324 #endif /* LWIP_TCP_TLP_SUPPORT */ 325 326 /** the TCP protocol control block for listening pcbs */ 327 struct tcp_pcb_listen { 328 /** Common members of all PCB types */ 329 IP_PCB; 330 /** Protocol specific PCB members */ 331 TCP_PCB_COMMON(struct tcp_pcb_listen); 332 333 #if LWIP_SO_PRIORITY 334 prio_t priority; 335 #endif /* LWIP_SO_PRIORITY */ 336 337 #if LWIP_CALLBACK_API 338 /* Function to call when a listener has been connected. */ 339 tcp_accept_fn accept; 340 #endif /* LWIP_CALLBACK_API */ 341 342 #if TCP_LISTEN_BACKLOG 343 u8_t backlog; 344 u8_t accepts_pending; 345 #endif /* TCP_LISTEN_BACKLOG */ 346 }; 347 348 #if DRIVER_STATUS_CHECK 349 #define TF_RST_ON_DRV_WAKE ((tcpflags_t)0x80000U) /* From loss receovery it entered to Retrasnmit timeout state */ 350 #endif 351 352 /** the TCP protocol control block */ 353 struct tcp_pcb { 354 /** common PCB members */ 355 IP_PCB; 356 /** protocol specific PCB members */ 357 TCP_PCB_COMMON(struct tcp_pcb); 358 359 #if LWIP_SO_PRIORITY 360 prio_t priority; 361 #endif /* LWIP_SO_PRIORITY */ 362 363 /* ports are in host byte order */ 364 u16_t remote_port; 365 366 tcpflags_t flags; 367 #define TF_ACK_DELAY 0x01U /* Delayed ACK. */ 368 #define TF_ACK_NOW 0x02U /* Immediate ACK. */ 369 #define TF_INFR 0x04U /* In fast recovery. */ 370 #define TF_CLOSEPEND 0x08U /* If this is set, tcp_close failed to enqueue the FIN (retried in tcp_tmr) */ 371 #define TF_RXCLOSED 0x10U /* rx closed by tcp_shutdown */ 372 #define TF_FIN 0x20U /* Connection was closed locally (FIN segment enqueued). */ 373 #define TF_NODELAY 0x40U /* Disable Nagle algorithm */ 374 #define TF_NAGLEMEMERR 0x80U /* nagle enabled, memerr, try to output to prevent delayed ACK to happen */ 375 #if LWIP_WND_SCALE 376 #define TF_WND_SCALE 0x0100U /* Window Scale option enabled */ 377 #endif 378 #if TCP_LISTEN_BACKLOG 379 #define TF_BACKLOGPEND 0x0200U /* If this is set, a connection pcb has increased the backlog on its listener */ 380 #endif 381 #if LWIP_TCP_TIMESTAMPS 382 #define TF_TIMESTAMP 0x0400U /* Timestamp option enabled */ 383 #endif 384 385 /* TCP flags for New Reno */ 386 #define TF_INFR_PACK ((tcpflags_t)0x1000U) /* Partial ACK recved flag */ 387 388 #define TF_RTO 0x0800U /* RTO timer has fired, in-flight data moved to unsent and being retransmitted */ 389 #define TF_INFR_FPACK ((tcpflags_t)0x4000U) /* Flag for wait for first parital ack */ 390 391 #if LWIP_SACK 392 /** TCP SACK option enabled. */ 393 #define TF_SACK ((tcpflags_t)0x10000U) 394 /** In SACK based Fast retransmit & loss recovery algorithm */ 395 #define TF_IN_SACK_FRLR ((tcpflags_t)0x20000U) 396 /** From loss recovery, it entered to Retrasnmit timeout state. */ 397 #define TF_IN_SACK_RTO ((tcpflags_t)0x40000U) 398 #endif 399 400 #if DRIVER_STATUS_CHECK 401 /* Netif driver status */ 402 u8_t drv_status; /* 0 - Driver not ready. 1- Driver is ready */ 403 #endif 404 405 /* the rest of the fields are in host byte order 406 as we have to do some math with them */ 407 408 /* Timers */ 409 u8_t polltmr, pollinterval; 410 u8_t last_timer; 411 u32_t tmr; 412 413 /* receiver variables */ 414 u32_t rcv_nxt; /* next seqno expected */ 415 tcpwnd_size_t rcv_wnd; /* receiver window available */ 416 tcpwnd_size_t rcv_ann_wnd; /* receiver window to announce */ 417 u32_t rcv_ann_right_edge; /* announced right edge of window */ 418 419 /* Retransmission timer. */ 420 s16_t rtime; 421 422 u16_t mss; /* maximum segment size */ 423 u16_t rcv_mss; /* mss from peer side */ 424 425 /* RTT (round trip time) estimation variables */ 426 u32_t rttest; /* The start time of RTT sample in ms, the granularity is system tick */ 427 u32_t rtseq; /* sequence number being timed */ 428 s16_t sa; /* smoothed round-trip time, 8 times of SRTT in RFC6298 */ 429 s16_t sv; /* round-trip time variation, 4 times of RTTVAR in RFC6298 */ 430 431 s16_t rto; /* retransmission time-out (in ticks of TCP_SLOW_INTERVAL) */ 432 u8_t nrtx; /* number of retransmissions */ 433 434 /* fast retransmit/recovery */ 435 u8_t dupacks; 436 u32_t lastack; /* Highest acknowledged seqno. */ 437 438 /* congestion avoidance/control variables */ 439 tcpwnd_size_t iw; 440 tcpwnd_size_t cwnd; 441 tcpwnd_size_t ssthresh; 442 443 /* first byte following last rto byte */ 444 u32_t rto_end; 445 446 /* sender variables */ 447 u32_t snd_nxt; /* next new seqno to be sent */ 448 u32_t snd_sml; /* The last byte of the most recently transmitted small packet */ 449 u32_t snd_wl1, snd_wl2; /* Sequence and acknowledgement numbers of last 450 window update. */ 451 u32_t snd_lbb; /* Sequence number of next byte to be buffered. */ 452 tcpwnd_size_t snd_wnd; /* sender window */ 453 tcpwnd_size_t snd_wnd_max; /* the maximum sender window announced by the remote host */ 454 455 u32_t snd_buf; /* Available buffer space for sending (in bytes). */ 456 #if LWIP_WND_SCALE 457 #define TCP_SNDQUEUELEN_OVERFLOW (0x03ffffffU - 3) 458 #else /* LWIP_WND_SCALE */ 459 #define TCP_SNDQUEUELEN_OVERFLOW (0xffffU - 3) 460 #endif /* LWIP_WND_SCALE */ 461 tcpwnd_size_t snd_queuelen; /* Available buffer space for sending (in tcp_segs). */ 462 tcpwnd_size_t snd_queuelen_max; 463 tcpwnd_size_t snd_queuelen_lowat; 464 u32_t snd_buf_lowat; 465 466 #if TCP_OVERSIZE 467 /* Extra bytes available at the end of the last pbuf in unsent. */ 468 u16_t unsent_oversize; 469 #endif /* TCP_OVERSIZE */ 470 471 tcpwnd_size_t bytes_acked; 472 473 /* These are ordered by sequence number: */ 474 struct tcp_seg *unsent; /* Unsent (queued) segments. */ 475 struct tcp_seg *unacked; /* Sent but unacknowledged segments. */ 476 #if TCP_QUEUE_OOSEQ 477 struct tcp_seg *ooseq; /* Received out of sequence segments. */ 478 #endif /* TCP_QUEUE_OOSEQ */ 479 480 struct pbuf *refused_data; /* Data previously received but not yet taken by upper layer */ 481 482 #if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG 483 struct tcp_pcb_listen* listener; 484 #endif /* LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG */ 485 486 #if LWIP_CALLBACK_API 487 /* Function to be called when more send buffer space is available. */ 488 tcp_sent_fn sent; 489 /* Function to be called when (in-sequence) data has arrived. */ 490 tcp_recv_fn recv; 491 /* Function to be called when a connection has been set up. */ 492 tcp_connected_fn connected; 493 /* Function which is called periodically. */ 494 tcp_poll_fn poll; 495 /* Function to be called whenever a fatal error occurs. */ 496 tcp_err_fn errf; 497 #endif /* LWIP_CALLBACK_API */ 498 499 #if DRIVER_STATUS_CHECK 500 tcp_event_sndplus_fn sndplus; 501 #endif 502 503 #if LWIP_TCP_TIMESTAMPS 504 u32_t ts_lastacksent; 505 u32_t ts_recent; 506 #endif /* LWIP_TCP_TIMESTAMPS */ 507 508 /* idle time before KEEPALIVE is sent */ 509 u32_t keep_idle; 510 #if LWIP_TCP_KEEPALIVE 511 u32_t keep_intvl; 512 u32_t keep_cnt; 513 #endif /* LWIP_TCP_KEEPALIVE */ 514 515 /* Persist timer counter */ 516 u8_t persist_cnt; 517 /* Persist timer back-off */ 518 u8_t persist_backoff; 519 /* Number of persist probes */ 520 u8_t persist_probe; 521 522 /* KEEPALIVE counter */ 523 u8_t keep_cnt_sent; 524 525 u32_t last_payload_len; 526 527 u32_t fast_recovery_point; /* snd_nxt when enter fast recovery */ 528 529 #if LWIP_SACK 530 struct _sack_seq *sack_seq; 531 /* SACK based pipe algorthim Changes */ 532 /* Pipe to hold the number of octets available in network */ 533 u32_t pipe; 534 /* Recovery point for stopping loss recovery phase */ 535 u32_t recovery_point; 536 /* highest octet covered by any received SACK block */ 537 u32_t high_sacked; 538 539 /* Loss recovery check needs to be started from this seg instead of pcb->unacked */ 540 /* This excludes the rexmited and sacked seg from pcb->unacked */ 541 /* That means, next_seg_for_lr points to first unsacked and not retransmitted seg */ 542 543 /* Optimization of SACK based pipe algorthim */ 544 struct tcp_seg *next_seg_for_lr; 545 546 /* highest data trasnfered so far, equivalent to snd_nxt */ 547 u32_t high_data; 548 /* highest octet retransmitted so far, as part of SACK based loss recovery algorithm */ 549 u32_t high_rxt; 550 /* Rescure rxt as per loss recovery algorithm */ 551 u32_t rescue_rxt; 552 553 u32_t num_sacks; 554 u32_t ooseq_cnt; 555 556 #if LWIP_SACK_PERF_OPT 557 u32_t pkt_seq_num; // packet order on which they are transmitted out of stack 558 u32_t high_sacked_pkt_seq; 559 struct tcp_sack_fast_rxmited *fr_segs; /* List of fast retransmitted segments */ 560 struct tcp_sack_fast_rxmited *last_frseg; /* The latest fast retransmitted segment. This stores the latest 561 * fast retransmitted segment so that when more segments are retransmitted, 562 * it can be appended to this segmetn without iterating whole list */ 563 #if LWIP_SACK_CWND_OPT 564 tcpwnd_size_t recover_cwnd; 565 tcpwnd_size_t recover_ssthresh; 566 #endif /* LWIP_SACK_CWND_OPT */ 567 #endif /* LWIP_SACK_PERF_OPT */ 568 569 u32_t sacked; /* The total SACKed segments count */ 570 571 #if LWIP_FACK_THRESHOLD_BASED_FR 572 u32_t fack; 573 #endif /* LWIP_FACK_THRESHOLD_BASED_FR */ 574 575 #if LWIP_TCP_TLP_SUPPORT 576 u8_t tlp_pto_cnt; /* Consecutive PTOs */ 577 u8_t tlp_rtx_out; /* the number of unacknowledged TLP retransmissions in current TLP episode */ 578 u32_t tlp_high_rxt; /* SND.NXT at the time it starts doing TLP transmissions during a given TLP episode */ 579 u32_t tlp_time_stamp; /* PTO trigger time in ms. 0 is one specially value which means PTO is not scheduled */ 580 #endif /* LWIP_TCP_TLP_SUPPORT */ 581 #endif /* LWIP_SACK */ 582 583 #if LWIP_WND_SCALE 584 u8_t snd_scale; 585 u8_t rcv_scale; 586 #endif 587 588 u8_t tcp_pcb_flag; 589 }; 590 591 #if LWIP_EVENT_API 592 593 enum lwip_event { 594 LWIP_EVENT_ACCEPT, 595 LWIP_EVENT_SENT, 596 LWIP_EVENT_RECV, 597 LWIP_EVENT_CONNECTED, 598 LWIP_EVENT_POLL, 599 LWIP_EVENT_ERR 600 }; 601 602 err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb, 603 enum lwip_event, 604 struct pbuf *p, 605 u16_t size, 606 err_t err); 607 608 #endif /* LWIP_EVENT_API */ 609 610 /* Application program's interface: */ 611 struct tcp_pcb * tcp_new (void); 612 struct tcp_pcb * tcp_new_ip_type (u8_t type); 613 614 void tcp_arg (struct tcp_pcb *pcb, void *arg); 615 #if LWIP_CALLBACK_API 616 void tcp_recv (struct tcp_pcb *pcb, tcp_recv_fn recv); 617 void tcp_sent (struct tcp_pcb *pcb, tcp_sent_fn sent); 618 void tcp_err (struct tcp_pcb *pcb, tcp_err_fn err); 619 void tcp_accept (struct tcp_pcb *pcb, tcp_accept_fn accept); 620 #endif /* LWIP_CALLBACK_API */ 621 void tcp_poll (struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval); 622 623 #if LWIP_LOWPOWER 624 u32_t tcp_fast_tmr_tick(void); 625 u32_t tcp_slow_tmr_tick(void); 626 #endif 627 628 #define tcp_set_flags(pcb, set_flags) do { (pcb)->flags = (tcpflags_t)((pcb)->flags | (set_flags)); } while(0) 629 #define tcp_clear_flags(pcb, clr_flags) do { (pcb)->flags = (tcpflags_t)((pcb)->flags & (tcpflags_t)(~(clr_flags) & TCP_ALLFLAGS)); } while(0) 630 #define tcp_is_flag_set(pcb, flag) (((pcb)->flags & (flag)) != 0) 631 632 #if LWIP_TCP_TIMESTAMPS 633 #define tcp_mss(pcb) (((pcb)->flags & TF_TIMESTAMP) ? ((pcb)->mss - 12) : (pcb)->mss) 634 #else /* LWIP_TCP_TIMESTAMPS */ 635 /** @ingroup tcp_raw */ 636 #define tcp_mss(pcb) ((pcb)->mss) 637 #endif /* LWIP_TCP_TIMESTAMPS */ 638 /** @ingroup tcp_raw */ 639 #define tcp_sndbuf(pcb) ((pcb)->snd_buf) 640 /** @ingroup tcp_raw */ 641 #define tcp_sndqueuelen(pcb) ((pcb)->snd_queuelen) 642 /** @ingroup tcp_raw */ 643 #define tcp_nagle_disable(pcb) tcp_set_flags(pcb, TF_NODELAY) 644 /** @ingroup tcp_raw */ 645 #define tcp_nagle_enable(pcb) tcp_clear_flags(pcb, TF_NODELAY) 646 /** @ingroup tcp_raw */ 647 #define tcp_nagle_disabled(pcb) tcp_is_flag_set(pcb, TF_NODELAY) 648 #if LWIP_SO_SNDBUF 649 #define tcp_set_sendbufsize(pcb, size) ((pcb)->snd_buf_static = (size)) 650 #define tcp_get_sendbufsize(pcb) ((pcb)->snd_buf_static) 651 #endif /* LWIP_SO_SNDBUF */ 652 653 #if TCP_LISTEN_BACKLOG 654 #define tcp_backlog_set(pcb, new_backlog) do { \ 655 LWIP_ASSERT("pcb->state == LISTEN (called for wrong pcb?)", (pcb)->state == LISTEN); \ 656 ((struct tcp_pcb_listen *)(pcb))->backlog = ((new_backlog) ? (new_backlog) : 1); } while(0) 657 void tcp_backlog_delayed(struct tcp_pcb* pcb); 658 void tcp_backlog_accepted(struct tcp_pcb* pcb); 659 #else /* TCP_LISTEN_BACKLOG */ 660 #define tcp_backlog_set(pcb, new_backlog) 661 #define tcp_backlog_delayed(pcb) 662 #define tcp_backlog_accepted(pcb) 663 #endif /* TCP_LISTEN_BACKLOG */ 664 #define tcp_accepted(pcb) do { LWIP_UNUSED_ARG(pcb); } while(0) /* compatibility define, not needed any more */ 665 666 void tcp_recved (struct tcp_pcb *pcb, u16_t len); 667 err_t tcp_bind (struct tcp_pcb *pcb, const ip_addr_t *ipaddr, 668 u16_t port); 669 void tcp_bind_netif(struct tcp_pcb *pcb, const struct netif *netif); 670 err_t tcp_connect (struct tcp_pcb *pcb, const ip_addr_t *ipaddr, 671 u16_t port, tcp_connected_fn connected); 672 673 struct tcp_pcb * tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u8_t backlog, err_t *err); 674 struct tcp_pcb * tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog); 675 /** @ingroup tcp_raw */ 676 #define tcp_listen(pcb) tcp_listen_with_backlog(pcb, TCP_DEFAULT_LISTEN_BACKLOG) 677 678 void tcp_abort (struct tcp_pcb *pcb); 679 err_t tcp_close (struct tcp_pcb *pcb); 680 err_t tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx); 681 682 err_t tcp_write (struct tcp_pcb *pcb, const void *dataptr, u16_t len, 683 u8_t apiflags); 684 685 void tcp_setprio (struct tcp_pcb *pcb, u8_t prio); 686 687 #if LWIP_TCP_TLP_SUPPORT 688 /* 689 * This is the TLP probe timeout function as in draft-dukkipati-tcpm-tcp-loss-probe-01 690 * 691 * When PTO fires: 692 * (a) If a new previously unsent segment exists: 693 * -> Transmit new segment. 694 * -> FlightSize += SMSS. cwnd remains unchanged. 695 * (b) If no new segment exists: 696 * -> Retransmit the last segment. 697 * (c) Increment statistics counter for loss probes. 698 * (d) If conditions in (2) are satisfied: 699 * -> Reschedule next PTO. 700 * Else: 701 * -> Rearm RTO to fire at epoch 'now+RTO'. 702 * 703 * @param pcb Protocol control block for the TCP connection to send data 704 * @return None 705 * 706 */ 707 void tcp_pto_fire(struct tcp_pcb *pcb); 708 #endif 709 710 err_t tcp_output (struct tcp_pcb *pcb); 711 712 err_t tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif); 713 714 err_t tcp_tcp_get_tcp_addrinfo(struct tcp_pcb *pcb, int local, ip_addr_t *addr, u16_t *port); 715 716 #define tcp_dbg_get_tcp_state(pcb) ((pcb)->state) 717 718 #if DRIVER_STATUS_CHECK 719 unsigned char tcp_is_netif_addr_check_success(const struct tcp_pcb *pcb, const struct netif *netif); 720 void tcp_flush_pcb_on_wake_queue(struct tcp_pcb *pcb, u8_t status); 721 void tcpip_flush_on_wake_queue(const struct netif *netif, u8_t status); 722 void tcp_ip_flush_pcblist_on_wake_queue(const struct netif *netif, struct tcp_pcb *pcb_list, u8_t status); 723 void tcpip_upd_status_to_tcp_pcbs(const struct netif *netif, u8_t status); 724 void tcp_ip_event_sendplus_on_wake_queue(const struct netif *netif); 725 void tcp_update_drv_status_to_pcbs(struct tcp_pcb *pcb_list, const struct netif *netif, u8_t status); 726 #endif 727 728 /* for compatibility with older implementation */ 729 #define tcp_new_ip6() tcp_new_ip_type(IPADDR_TYPE_V6) 730 731 void tcp_sndbuf_init(struct tcp_pcb *pcb); 732 733 #if LWIP_TCP_PCB_NUM_EXT_ARGS 734 u8_t tcp_ext_arg_alloc_id(void); 735 void tcp_ext_arg_set_callbacks(struct tcp_pcb *pcb, uint8_t id, const struct tcp_ext_arg_callbacks * const callbacks); 736 void tcp_ext_arg_set(struct tcp_pcb *pcb, uint8_t id, void *arg); 737 void *tcp_ext_arg_get(const struct tcp_pcb *pcb, uint8_t id); 738 #endif 739 740 #if LWIP_TCP_TLP_SUPPORT 741 void tcp_tlp_schedule_probe(struct tcp_pcb *pcb, u32_t wnd); 742 #endif /* LWIP_TCP_TLP_SUPPORT */ 743 744 extern const char * const tcp_state_str[]; 745 746 #ifdef __cplusplus 747 } 748 #endif 749 750 #endif /* LWIP_TCP */ 751 752 #endif /* LWIP_HDR_TCP_H */ 753