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/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 53 #ifdef __cplusplus 54 extern "C" { 55 #endif 56 57 /* 0:weak signal use large rto 58 * 1:strong singal use small rto */ 59 #define RTO_FLAGS_LARGE 0 60 #define RTO_FLAGS_SMALL 1 61 #define RTO_FLAGS_DEFAULT 2 62 /* 0:small rto 1:large rto */ 63 extern int lwip_rto_flags; 64 65 /* 1:strong signal use large rcv wnd 66 * 0:weak signal use small rcv wnd 67 * 2:default rcv wnd */ 68 #define WND_FLAGS_LARGE 0 69 #define WND_FLAGS_SMALL 1 70 #define WND_FLAGS_DEFAULT 2 71 72 #define TCP_SMALL_WND (6*TCP_MSS) 73 #define TCP_LARGE_WND (44*TCP_MSS) 74 75 #define TCP_SMALL_RTO (500) 76 #define TCP_LARGE_RTO (500) 77 /* 0:small rcv wnd 1:large rcv wnd */ 78 extern int lwip_rcv_wnd_flags; 79 80 struct tcp_pcb; 81 82 /** Function prototype for tcp accept callback functions. Called when a new 83 * connection can be accepted on a listening pcb. 84 * 85 * @param arg Additional argument to pass to the callback function (@see tcp_arg()) 86 * @param newpcb The new connection pcb 87 * @param err An error code if there has been an error accepting. 88 * Only return ERR_ABRT if you have called tcp_abort from within the 89 * callback function! 90 */ 91 typedef err_t (*tcp_accept_fn)(void *arg, struct tcp_pcb *newpcb, err_t err); 92 93 /** Function prototype for tcp receive callback functions. Called when data has 94 * been received. 95 * 96 * @param arg Additional argument to pass to the callback function (@see tcp_arg()) 97 * @param tpcb The connection pcb which received data 98 * @param p The received data (or NULL when the connection has been closed!) 99 * @param err An error code if there has been an error receiving 100 * Only return ERR_ABRT if you have called tcp_abort from within the 101 * callback function! 102 */ 103 typedef err_t (*tcp_recv_fn)(void *arg, struct tcp_pcb *tpcb, 104 struct pbuf *p, err_t err); 105 106 /** Function prototype for tcp sent callback functions. Called when sent data has 107 * been acknowledged by the remote side. Use it to free corresponding resources. 108 * This also means that the pcb has now space available to send new data. 109 * 110 * @param arg Additional argument to pass to the callback function (@see tcp_arg()) 111 * @param tpcb The connection pcb for which data has been acknowledged 112 * @param len The amount of bytes acknowledged 113 * @return ERR_OK: try to send some data by calling tcp_output 114 * Only return ERR_ABRT if you have called tcp_abort from within the 115 * callback function! 116 */ 117 typedef err_t (*tcp_sent_fn)(void *arg, struct tcp_pcb *tpcb, 118 u16_t len); 119 120 /** Function prototype for tcp poll callback functions. Called periodically as 121 * specified by @see tcp_poll. 122 * 123 * @param arg Additional argument to pass to the callback function (@see tcp_arg()) 124 * @param tpcb tcp pcb 125 * @return ERR_OK: try to send some data by calling tcp_output 126 * Only return ERR_ABRT if you have called tcp_abort from within the 127 * callback function! 128 */ 129 typedef err_t (*tcp_poll_fn)(void *arg, struct tcp_pcb *tpcb); 130 131 /** Function prototype for tcp error callback functions. Called when the pcb 132 * receives a RST or is unexpectedly closed for any other reason. 133 * 134 * @note The corresponding pcb is already freed when this callback is called! 135 * 136 * @param arg Additional argument to pass to the callback function (@see tcp_arg()) 137 * @param err Error code to indicate why the pcb has been closed 138 * ERR_ABRT: aborted through tcp_abort or by a TCP timer 139 * ERR_RST: the connection was reset by the remote host 140 */ 141 typedef void (*tcp_err_fn)(void *arg, err_t err); 142 143 /** Function prototype for tcp connected callback functions. Called when a pcb 144 * is connected to the remote side after initiating a connection attempt by 145 * calling tcp_connect(). 146 * 147 * @param arg Additional argument to pass to the callback function (@see tcp_arg()) 148 * @param tpcb The connection pcb which is connected 149 * @param err An unused error code, always ERR_OK currently ;-) @todo! 150 * Only return ERR_ABRT if you have called tcp_abort from within the 151 * callback function! 152 * 153 * @note When a connection attempt fails, the error callback is currently called! 154 */ 155 typedef err_t (*tcp_connected_fn)(void *arg, struct tcp_pcb *tpcb, err_t err); 156 157 #define TCP_DYNA_WND_MAX(pcb) \ 158 ((lwip_rcv_wnd_flags == WND_FLAGS_SMALL) ? TCP_SMALL_WND : \ 159 ((lwip_rcv_wnd_flags == WND_FLAGS_LARGE) ? TCP_LARGE_WND : \ 160 ((pcb->usr_rcv_wnd == 0) ? TCP_WND : pcb->usr_rcv_wnd))) 161 162 #if LWIP_WND_SCALE 163 #define RCV_WND_SCALE(pcb, wnd) (((wnd) >> (pcb)->rcv_scale)) 164 #define SND_WND_SCALE(pcb, wnd) (((wnd) << (pcb)->snd_scale)) 165 #define TCPWND16(x) ((u16_t)LWIP_MIN((x), 0xFFFF)) 166 #define TCP_WND_MAX(pcb) (tcpwnd_size_t)(((pcb)->flags & TF_WND_SCALE) ? TCP_DYNA_WND_MAX(pcb) : TCPWND16(TCP_DYNA_WND_MAX)) 167 168 typedef u32_t tcpwnd_size_t; 169 #else 170 #define RCV_WND_SCALE(pcb, wnd) (wnd) 171 #define SND_WND_SCALE(pcb, wnd) (wnd) 172 #define TCPWND16(x) (x) 173 174 #define TCP_WND_MAX(pcb) TCP_DYNA_WND_MAX(pcb) 175 176 typedef u16_t tcpwnd_size_t; 177 #endif 178 179 #if LWIP_WND_SCALE || TCP_LISTEN_BACKLOG 180 typedef u16_t tcpflags_t; 181 #else 182 typedef u8_t tcpflags_t; 183 #endif 184 185 enum tcp_state { 186 CLOSED = 0, 187 LISTEN = 1, 188 SYN_SENT = 2, 189 SYN_RCVD = 3, 190 ESTABLISHED = 4, 191 FIN_WAIT_1 = 5, 192 FIN_WAIT_2 = 6, 193 CLOSE_WAIT = 7, 194 CLOSING = 8, 195 LAST_ACK = 9, 196 TIME_WAIT = 10 197 }; 198 #if LWIP_TCP_SACK_OUT 199 /** SACK ranges to include in ACK packets. 200 * SACK entry is invalid if left==right. */ 201 struct tcp_sack_range { 202 /** Left edge of the SACK: the first acknowledged sequence number. */ 203 u32_t left; 204 /** Right edge of the SACK: the last acknowledged sequence number +1 (so first NOT acknowledged). */ 205 u32_t right; 206 }; 207 #endif /* LWIP_TCP_SACK_OUT */ 208 209 /** 210 * members common to struct tcp_pcb and struct tcp_listen_pcb 211 */ 212 #define TCP_PCB_COMMON(type) \ 213 type *next; /* for the linked list */ \ 214 void *callback_arg; \ 215 enum tcp_state state; /* TCP state */ \ 216 u8_t prio; \ 217 /* ports are in host byte order */ \ 218 u16_t local_port; \ 219 /* user use setsockopt to set tcp rcv wnd */ \ 220 tcpwnd_size_t usr_rcv_wnd 221 222 /** the TCP protocol control block for listening pcbs */ 223 struct tcp_pcb_listen { 224 /** Common members of all PCB types */ 225 IP_PCB; 226 /** Protocol specific PCB members */ 227 TCP_PCB_COMMON(struct tcp_pcb_listen); 228 229 #if LWIP_CALLBACK_API 230 /* Function to call when a listener has been connected. */ 231 tcp_accept_fn accept; 232 #endif /* LWIP_CALLBACK_API */ 233 234 #if TCP_LISTEN_BACKLOG 235 u8_t backlog; 236 u8_t accepts_pending; 237 #endif /* TCP_LISTEN_BACKLOG */ 238 }; 239 240 241 /** the TCP protocol control block */ 242 struct tcp_pcb { 243 /** common PCB members */ 244 IP_PCB; 245 /** protocol specific PCB members */ 246 TCP_PCB_COMMON(struct tcp_pcb); 247 248 /* ports are in host byte order */ 249 u16_t remote_port; 250 251 tcpflags_t flags; 252 #define TF_ACK_DELAY 0x01U /* Delayed ACK. */ 253 #define TF_ACK_NOW 0x02U /* Immediate ACK. */ 254 #define TF_INFR 0x04U /* In fast recovery. */ 255 #define TF_TIMESTAMP 0x08U /* Timestamp option enabled */ 256 #define TF_RXCLOSED 0x10U /* rx closed by tcp_shutdown */ 257 #define TF_FIN 0x20U /* Connection was closed locally (FIN segment enqueued). */ 258 #define TF_NODELAY 0x40U /* Disable Nagle algorithm */ 259 #define TF_NAGLEMEMERR 0x80U /* nagle enabled, memerr, try to output to prevent delayed ACK to happen */ 260 #if LWIP_WND_SCALE 261 #define TF_WND_SCALE 0x0100U /* Window Scale option enabled */ 262 #endif 263 #if TCP_LISTEN_BACKLOG 264 #define TF_BACKLOGPEND 0x0200U /* If this is set, a connection pcb has increased the backlog on its listener */ 265 #endif 266 #if LWIP_TCP_SACK_OUT 267 #define TF_SACK 0x1000U /* Selective ACKs enabled */ 268 #endif 269 270 /* the rest of the fields are in host byte order 271 as we have to do some math with them */ 272 273 /* Timers */ 274 u8_t polltmr, pollinterval; 275 u8_t last_timer; 276 u32_t tmr; 277 278 /* receiver variables */ 279 u32_t rcv_nxt; /* next seqno expected */ 280 tcpwnd_size_t rcv_wnd; /* receiver window available */ 281 tcpwnd_size_t rcv_ann_wnd; /* receiver window to announce */ 282 u32_t rcv_ann_right_edge; /* announced right edge of window */ 283 284 #if LWIP_TCP_SACK_OUT 285 /* SACK ranges to include in ACK packets (entry is invalid if left==right) */ 286 struct tcp_sack_range rcv_sacks[LWIP_TCP_MAX_SACK_NUM]; 287 #define LWIP_TCP_SACK_VALID(pcb, idx) ((pcb)->rcv_sacks[idx].left != (pcb)->rcv_sacks[idx].right) 288 #endif /* LWIP_TCP_SACK_OUT */ 289 290 /* Retransmission timer. */ 291 s16_t rtime; 292 293 u16_t mss; /* maximum segment size */ 294 295 /* RTT (round trip time) estimation variables */ 296 u32_t rttest; /* RTT estimate in 500ms ticks */ 297 u32_t rtseq; /* sequence number being timed */ 298 s16_t sa, sv; /* @todo document this */ 299 300 s16_t rto; /* retransmission time-out */ 301 s16_t adjrto; /* adjust retransmission time-out */ 302 u8_t nrtx; /* number of retransmissions */ 303 304 /* fast retransmit/recovery */ 305 u8_t dupacks; 306 u32_t lastack; /* Highest acknowledged seqno. */ 307 308 /* congestion avoidance/control variables */ 309 tcpwnd_size_t cwnd; 310 tcpwnd_size_t ssthresh; 311 312 /* sender variables */ 313 u32_t snd_nxt; /* next new seqno to be sent */ 314 u32_t snd_wl1, snd_wl2; /* Sequence and acknowledgement numbers of last 315 window update. */ 316 u32_t snd_lbb; /* Sequence number of next byte to be buffered. */ 317 tcpwnd_size_t snd_wnd; /* sender window */ 318 tcpwnd_size_t snd_wnd_max; /* the maximum sender window announced by the remote host */ 319 320 tcpwnd_size_t snd_buf; /* Available buffer space for sending (in bytes). */ 321 #define TCP_SNDQUEUELEN_OVERFLOW (0xffffU-3) 322 u16_t snd_queuelen; /* Number of pbufs currently in the send buffer. */ 323 324 #if TCP_OVERSIZE 325 /* Extra bytes available at the end of the last pbuf in unsent. */ 326 u16_t unsent_oversize; 327 #endif /* TCP_OVERSIZE */ 328 329 /* These are ordered by sequence number: */ 330 struct tcp_seg *unsent; /* Unsent (queued) segments. */ 331 struct tcp_seg *unacked; /* Sent but unacknowledged segments. */ 332 #if TCP_QUEUE_OOSEQ 333 struct tcp_seg *ooseq; /* Received out of sequence segments. */ 334 #endif /* TCP_QUEUE_OOSEQ */ 335 336 struct pbuf *refused_data; /* Data previously received but not yet taken by upper layer */ 337 338 #if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG 339 struct tcp_pcb_listen* listener; 340 #endif /* LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG */ 341 342 #if LWIP_CALLBACK_API 343 /* Function to be called when more send buffer space is available. */ 344 tcp_sent_fn sent; 345 /* Function to be called when (in-sequence) data has arrived. */ 346 tcp_recv_fn recv; 347 /* Function to be called when a connection has been set up. */ 348 tcp_connected_fn connected; 349 /* Function which is called periodically. */ 350 tcp_poll_fn poll; 351 /* Function to be called whenever a fatal error occurs. */ 352 tcp_err_fn errf; 353 #endif /* LWIP_CALLBACK_API */ 354 355 #if LWIP_TCP_TIMESTAMPS 356 u32_t ts_lastacksent; 357 u32_t ts_recent; 358 #endif /* LWIP_TCP_TIMESTAMPS */ 359 360 /* idle time before KEEPALIVE is sent */ 361 u32_t keep_idle; 362 #if LWIP_TCP_KEEPALIVE 363 u32_t keep_intvl; 364 u32_t keep_cnt; 365 #endif /* LWIP_TCP_KEEPALIVE */ 366 367 /* Persist timer counter */ 368 u8_t persist_cnt; 369 /* Persist timer back-off */ 370 u8_t persist_backoff; 371 372 /* KEEPALIVE counter */ 373 u8_t keep_cnt_sent; 374 375 #if LWIP_WND_SCALE 376 u8_t snd_scale; 377 u8_t rcv_scale; 378 #endif 379 }; 380 381 #if LWIP_EVENT_API 382 383 enum lwip_event { 384 LWIP_EVENT_ACCEPT, 385 LWIP_EVENT_SENT, 386 LWIP_EVENT_RECV, 387 LWIP_EVENT_CONNECTED, 388 LWIP_EVENT_POLL, 389 LWIP_EVENT_ERR 390 }; 391 392 err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb, 393 enum lwip_event, 394 struct pbuf *p, 395 u16_t size, 396 err_t err); 397 398 #endif /* LWIP_EVENT_API */ 399 400 /* Application program's interface: */ 401 struct tcp_pcb * tcp_new (void); 402 struct tcp_pcb * tcp_new_ip_type (u8_t type); 403 404 void tcp_arg (struct tcp_pcb *pcb, void *arg); 405 void tcp_setrcvwnd (struct tcp_pcb *pcb, u32_t newwnd); 406 #if LWIP_CALLBACK_API 407 void tcp_recv (struct tcp_pcb *pcb, tcp_recv_fn recv); 408 void tcp_sent (struct tcp_pcb *pcb, tcp_sent_fn sent); 409 void tcp_err (struct tcp_pcb *pcb, tcp_err_fn err); 410 void tcp_accept (struct tcp_pcb *pcb, tcp_accept_fn accept); 411 #endif /* LWIP_CALLBACK_API */ 412 void tcp_poll (struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval); 413 414 #define tcp_mss(pcb) (((pcb)->flags & TF_TIMESTAMP) ? ((pcb)->mss - 12) : (pcb)->mss) 415 #define tcp_sndbuf(pcb) (TCPWND16((pcb)->snd_buf)) 416 #define tcp_sndqueuelen(pcb) ((pcb)->snd_queuelen) 417 /** @ingroup tcp_raw */ 418 #define tcp_nagle_disable(pcb) ((pcb)->flags |= TF_NODELAY) 419 /** @ingroup tcp_raw */ 420 #define tcp_nagle_enable(pcb) ((pcb)->flags = (tcpflags_t)((pcb)->flags & ~TF_NODELAY)) 421 /** @ingroup tcp_raw */ 422 #define tcp_nagle_disabled(pcb) (((pcb)->flags & TF_NODELAY) != 0) 423 424 #if TCP_LISTEN_BACKLOG 425 #define tcp_backlog_set(pcb, new_backlog) do { \ 426 LWIP_ASSERT("pcb->state == LISTEN (called for wrong pcb?)", (pcb)->state == LISTEN); \ 427 ((struct tcp_pcb_listen *)(pcb))->backlog = ((new_backlog) ? (new_backlog) : 1); } while(0) 428 void tcp_backlog_delayed(struct tcp_pcb* pcb); 429 void tcp_backlog_accepted(struct tcp_pcb* pcb); 430 #else /* TCP_LISTEN_BACKLOG */ 431 #define tcp_backlog_set(pcb, new_backlog) 432 #define tcp_backlog_delayed(pcb) 433 #define tcp_backlog_accepted(pcb) 434 #endif /* TCP_LISTEN_BACKLOG */ 435 #define tcp_accepted(pcb) /* compatibility define, not needed any more */ 436 437 void tcp_recved (struct tcp_pcb *pcb, u16_t len); 438 err_t tcp_bind (struct tcp_pcb *pcb, const ip_addr_t *ipaddr, 439 u16_t port); 440 err_t tcp_connect (struct tcp_pcb *pcb, const ip_addr_t *ipaddr, 441 u16_t port, tcp_connected_fn connected); 442 443 struct tcp_pcb * tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog); 444 /** @ingroup tcp_raw */ 445 #define tcp_listen(pcb) tcp_listen_with_backlog(pcb, TCP_DEFAULT_LISTEN_BACKLOG) 446 447 void tcp_abort (struct tcp_pcb *pcb); 448 err_t tcp_close (struct tcp_pcb *pcb); 449 err_t tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx); 450 451 /* Flags for "apiflags" parameter in tcp_write */ 452 #define TCP_WRITE_FLAG_COPY 0x01 453 #define TCP_WRITE_FLAG_MORE 0x02 454 455 err_t tcp_write (struct tcp_pcb *pcb, const void *dataptr, u16_t len, 456 u8_t apiflags); 457 458 void tcp_setprio (struct tcp_pcb *pcb, u8_t prio); 459 460 #define TCP_PRIO_MIN 1 461 #define TCP_PRIO_NORMAL 64 462 #define TCP_PRIO_MAX 127 463 464 err_t tcp_output (struct tcp_pcb *pcb); 465 466 467 const char* tcp_debug_state_str(enum tcp_state s); 468 469 /* for compatibility with older implementation */ 470 #define tcp_new_ip6() tcp_new_ip_type(IPADDR_TYPE_V6) 471 472 #ifdef __cplusplus 473 } 474 #endif 475 476 #endif /* LWIP_TCP */ 477 478 #endif /* LWIP_HDR_TCP_H */ 479