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