Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of F7_Ethernet by
tcp_impl.h
00001 /* 00002 * Copyright (c) 2001-2004 Swedish Institute of Computer Science. 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without modification, 00006 * are permitted provided that the following conditions are met: 00007 * 00008 * 1. Redistributions of source code must retain the above copyright notice, 00009 * this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright notice, 00011 * this list of conditions and the following disclaimer in the documentation 00012 * and/or other materials provided with the distribution. 00013 * 3. The name of the author may not be used to endorse or promote products 00014 * derived from this software without specific prior written permission. 00015 * 00016 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 00017 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00018 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 00019 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00020 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 00021 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00022 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00023 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 00024 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 00025 * OF SUCH DAMAGE. 00026 * 00027 * This file is part of the lwIP TCP/IP stack. 00028 * 00029 * Author: Adam Dunkels <adam@sics.se> 00030 * 00031 */ 00032 #ifndef __LWIP_TCP_IMPL_H__ 00033 #define __LWIP_TCP_IMPL_H__ 00034 00035 #include "lwip/opt.h" 00036 00037 #if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ 00038 00039 #include "lwip/tcp.h" 00040 #include "lwip/mem.h" 00041 #include "lwip/pbuf.h" 00042 #include "lwip/ip.h" 00043 #include "lwip/icmp.h" 00044 #include "lwip/err.h" 00045 00046 #ifdef __cplusplus 00047 extern "C" { 00048 #endif 00049 00050 /* Functions for interfacing with TCP: */ 00051 00052 /* Lower layer interface to TCP: */ 00053 void tcp_init (void); /* Initialize this module. */ 00054 void tcp_tmr (void); /* Must be called every 00055 TCP_TMR_INTERVAL 00056 ms. (Typically 250 ms). */ 00057 /* It is also possible to call these two functions at the right 00058 intervals (instead of calling tcp_tmr()). */ 00059 void tcp_slowtmr (void); 00060 void tcp_fasttmr (void); 00061 00062 00063 /* Only used by IP to pass a TCP segment to TCP: */ 00064 void tcp_input (struct pbuf *p, struct netif *inp); 00065 /* Used within the TCP code only: */ 00066 struct tcp_pcb * tcp_alloc (u8_t prio); 00067 void tcp_abandon (struct tcp_pcb *pcb, int reset); 00068 err_t tcp_send_empty_ack(struct tcp_pcb *pcb); 00069 void tcp_rexmit (struct tcp_pcb *pcb); 00070 void tcp_rexmit_rto (struct tcp_pcb *pcb); 00071 void tcp_rexmit_fast (struct tcp_pcb *pcb); 00072 u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb); 00073 err_t tcp_process_refused_data(struct tcp_pcb *pcb); 00074 00075 /** 00076 * This is the Nagle algorithm: try to combine user data to send as few TCP 00077 * segments as possible. Only send if 00078 * - no previously transmitted data on the connection remains unacknowledged or 00079 * - the TF_NODELAY flag is set (nagle algorithm turned off for this pcb) or 00080 * - the only unsent segment is at least pcb->mss bytes long (or there is more 00081 * than one unsent segment - with lwIP, this can happen although unsent->len < mss) 00082 * - or if we are in fast-retransmit (TF_INFR) 00083 */ 00084 #define tcp_do_output_nagle(tpcb) ((((tpcb)->unacked == NULL) || \ 00085 ((tpcb)->flags & (TF_NODELAY | TF_INFR)) || \ 00086 (((tpcb)->unsent != NULL) && (((tpcb)->unsent->next != NULL) || \ 00087 ((tpcb)->unsent->len >= (tpcb)->mss))) || \ 00088 ((tcp_sndbuf(tpcb) == 0) || (tcp_sndqueuelen(tpcb) >= TCP_SND_QUEUELEN)) \ 00089 ) ? 1 : 0) 00090 #define tcp_output_nagle(tpcb) (tcp_do_output_nagle(tpcb) ? tcp_output(tpcb) : ERR_OK) 00091 00092 00093 #define TCP_SEQ_LT(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) < 0) 00094 #define TCP_SEQ_LEQ(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) <= 0) 00095 #define TCP_SEQ_GT(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) > 0) 00096 #define TCP_SEQ_GEQ(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) >= 0) 00097 /* is b<=a<=c? */ 00098 #if 0 /* see bug #10548 */ 00099 #define TCP_SEQ_BETWEEN(a,b,c) ((c)-(b) >= (a)-(b)) 00100 #endif 00101 #define TCP_SEQ_BETWEEN(a,b,c) (TCP_SEQ_GEQ(a,b) && TCP_SEQ_LEQ(a,c)) 00102 #define TCP_FIN 0x01U 00103 #define TCP_SYN 0x02U 00104 #define TCP_RST 0x04U 00105 #define TCP_PSH 0x08U 00106 #define TCP_ACK 0x10U 00107 #define TCP_URG 0x20U 00108 #define TCP_ECE 0x40U 00109 #define TCP_CWR 0x80U 00110 00111 #define TCP_FLAGS 0x3fU 00112 00113 /* Length of the TCP header, excluding options. */ 00114 #define TCP_HLEN 20 00115 00116 #ifndef TCP_TMR_INTERVAL 00117 #define TCP_TMR_INTERVAL 250 /* The TCP timer interval in milliseconds. */ 00118 #endif /* TCP_TMR_INTERVAL */ 00119 00120 #ifndef TCP_FAST_INTERVAL 00121 #define TCP_FAST_INTERVAL TCP_TMR_INTERVAL /* the fine grained timeout in milliseconds */ 00122 #endif /* TCP_FAST_INTERVAL */ 00123 00124 #ifndef TCP_SLOW_INTERVAL 00125 #define TCP_SLOW_INTERVAL (2*TCP_TMR_INTERVAL) /* the coarse grained timeout in milliseconds */ 00126 #endif /* TCP_SLOW_INTERVAL */ 00127 00128 #define TCP_FIN_WAIT_TIMEOUT 20000 /* milliseconds */ 00129 #define TCP_SYN_RCVD_TIMEOUT 20000 /* milliseconds */ 00130 00131 #define TCP_OOSEQ_TIMEOUT 6U /* x RTO */ 00132 00133 #ifndef TCP_MSL 00134 #define TCP_MSL 60000UL /* The maximum segment lifetime in milliseconds */ 00135 #endif 00136 00137 /* Keepalive values, compliant with RFC 1122. Don't change this unless you know what you're doing */ 00138 #ifndef TCP_KEEPIDLE_DEFAULT 00139 #define TCP_KEEPIDLE_DEFAULT 7200000UL /* Default KEEPALIVE timer in milliseconds */ 00140 #endif 00141 00142 #ifndef TCP_KEEPINTVL_DEFAULT 00143 #define TCP_KEEPINTVL_DEFAULT 75000UL /* Default Time between KEEPALIVE probes in milliseconds */ 00144 #endif 00145 00146 #ifndef TCP_KEEPCNT_DEFAULT 00147 #define TCP_KEEPCNT_DEFAULT 9U /* Default Counter for KEEPALIVE probes */ 00148 #endif 00149 00150 #define TCP_MAXIDLE TCP_KEEPCNT_DEFAULT * TCP_KEEPINTVL_DEFAULT /* Maximum KEEPALIVE probe time */ 00151 00152 /* Fields are (of course) in network byte order. 00153 * Some fields are converted to host byte order in tcp_input(). 00154 */ 00155 #ifdef PACK_STRUCT_USE_INCLUDES 00156 # include "arch/bpstruct.h" 00157 #endif 00158 PACK_STRUCT_BEGIN 00159 struct tcp_hdr { 00160 PACK_STRUCT_FIELD(u16_t src); 00161 PACK_STRUCT_FIELD(u16_t dest); 00162 PACK_STRUCT_FIELD(u32_t seqno); 00163 PACK_STRUCT_FIELD(u32_t ackno); 00164 PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags); 00165 PACK_STRUCT_FIELD(u16_t wnd); 00166 PACK_STRUCT_FIELD(u16_t chksum); 00167 PACK_STRUCT_FIELD(u16_t urgp); 00168 } PACK_STRUCT_STRUCT; 00169 PACK_STRUCT_END 00170 #ifdef PACK_STRUCT_USE_INCLUDES 00171 # include "arch/epstruct.h" 00172 #endif 00173 00174 #define TCPH_HDRLEN(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 12) 00175 #define TCPH_FLAGS(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS) 00176 00177 #define TCPH_HDRLEN_SET(phdr, len) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | TCPH_FLAGS(phdr)) 00178 #define TCPH_FLAGS_SET(phdr, flags) (phdr)->_hdrlen_rsvd_flags = (((phdr)->_hdrlen_rsvd_flags & PP_HTONS((u16_t)(~(u16_t)(TCP_FLAGS)))) | htons(flags)) 00179 #define TCPH_HDRLEN_FLAGS_SET(phdr, len, flags) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | (flags)) 00180 00181 #define TCPH_SET_FLAG(phdr, flags ) (phdr)->_hdrlen_rsvd_flags = ((phdr)->_hdrlen_rsvd_flags | htons(flags)) 00182 #define TCPH_UNSET_FLAG(phdr, flags) (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (TCPH_FLAGS(phdr) & ~(flags)) ) 00183 00184 #define TCP_TCPLEN(seg) ((seg)->len + ((TCPH_FLAGS((seg)->tcphdr) & (TCP_FIN | TCP_SYN)) != 0)) 00185 00186 /** Flags used on input processing, not on pcb->flags 00187 */ 00188 #define TF_RESET (u8_t)0x08U /* Connection was reset. */ 00189 #define TF_CLOSED (u8_t)0x10U /* Connection was sucessfully closed. */ 00190 #define TF_GOT_FIN (u8_t)0x20U /* Connection was closed by the remote end. */ 00191 00192 00193 #if LWIP_EVENT_API 00194 00195 #define TCP_EVENT_ACCEPT(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ 00196 LWIP_EVENT_ACCEPT, NULL, 0, err) 00197 #define TCP_EVENT_SENT(pcb,space,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ 00198 LWIP_EVENT_SENT, NULL, space, ERR_OK) 00199 #define TCP_EVENT_RECV(pcb,p,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ 00200 LWIP_EVENT_RECV, (p), 0, (err)) 00201 #define TCP_EVENT_CLOSED(pcb,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ 00202 LWIP_EVENT_RECV, NULL, 0, ERR_OK) 00203 #define TCP_EVENT_CONNECTED(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ 00204 LWIP_EVENT_CONNECTED, NULL, 0, (err)) 00205 #define TCP_EVENT_POLL(pcb,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ 00206 LWIP_EVENT_POLL, NULL, 0, ERR_OK) 00207 #define TCP_EVENT_ERR(errf,arg,err) lwip_tcp_event((arg), NULL, \ 00208 LWIP_EVENT_ERR, NULL, 0, (err)) 00209 00210 #else /* LWIP_EVENT_API */ 00211 00212 #define TCP_EVENT_ACCEPT(pcb,err,ret) \ 00213 do { \ 00214 if((pcb)->accept != NULL) \ 00215 (ret) = (pcb)->accept((pcb)->callback_arg,(pcb),(err)); \ 00216 else (ret) = ERR_ARG; \ 00217 } while (0) 00218 00219 #define TCP_EVENT_SENT(pcb,space,ret) \ 00220 do { \ 00221 if((pcb)->sent != NULL) \ 00222 (ret) = (pcb)->sent((pcb)->callback_arg,(pcb),(space)); \ 00223 else (ret) = ERR_OK; \ 00224 } while (0) 00225 00226 #define TCP_EVENT_RECV(pcb,p,err,ret) \ 00227 do { \ 00228 if((pcb)->recv != NULL) { \ 00229 (ret) = (pcb)->recv((pcb)->callback_arg,(pcb),(p),(err));\ 00230 } else { \ 00231 (ret) = tcp_recv_null(NULL, (pcb), (p), (err)); \ 00232 } \ 00233 } while (0) 00234 00235 #define TCP_EVENT_CLOSED(pcb,ret) \ 00236 do { \ 00237 if(((pcb)->recv != NULL)) { \ 00238 (ret) = (pcb)->recv((pcb)->callback_arg,(pcb),NULL,ERR_OK);\ 00239 } else { \ 00240 (ret) = ERR_OK; \ 00241 } \ 00242 } while (0) 00243 00244 #define TCP_EVENT_CONNECTED(pcb,err,ret) \ 00245 do { \ 00246 if((pcb)->connected != NULL) \ 00247 (ret) = (pcb)->connected((pcb)->callback_arg,(pcb),(err)); \ 00248 else (ret) = ERR_OK; \ 00249 } while (0) 00250 00251 #define TCP_EVENT_POLL(pcb,ret) \ 00252 do { \ 00253 if((pcb)->poll != NULL) \ 00254 (ret) = (pcb)->poll((pcb)->callback_arg,(pcb)); \ 00255 else (ret) = ERR_OK; \ 00256 } while (0) 00257 00258 #define TCP_EVENT_ERR(errf,arg,err) \ 00259 do { \ 00260 if((errf) != NULL) \ 00261 (errf)((arg),(err)); \ 00262 } while (0) 00263 00264 #endif /* LWIP_EVENT_API */ 00265 00266 /** Enabled extra-check for TCP_OVERSIZE if LWIP_DEBUG is enabled */ 00267 #if TCP_OVERSIZE && defined(LWIP_DEBUG) 00268 #define TCP_OVERSIZE_DBGCHECK 1 00269 #else 00270 #define TCP_OVERSIZE_DBGCHECK 0 00271 #endif 00272 00273 /** Don't generate checksum on copy if CHECKSUM_GEN_TCP is disabled */ 00274 #define TCP_CHECKSUM_ON_COPY (LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_TCP) 00275 00276 /* This structure represents a TCP segment on the unsent, unacked and ooseq queues */ 00277 struct tcp_seg { 00278 struct tcp_seg *next; /* used when putting segements on a queue */ 00279 struct pbuf *p; /* buffer containing data + TCP header */ 00280 u16_t len; /* the TCP length of this segment */ 00281 #if TCP_OVERSIZE_DBGCHECK 00282 u16_t oversize_left; /* Extra bytes available at the end of the last 00283 pbuf in unsent (used for asserting vs. 00284 tcp_pcb.unsent_oversized only) */ 00285 #endif /* TCP_OVERSIZE_DBGCHECK */ 00286 #if TCP_CHECKSUM_ON_COPY 00287 u16_t chksum; 00288 u8_t chksum_swapped; 00289 #endif /* TCP_CHECKSUM_ON_COPY */ 00290 u8_t flags; 00291 #define TF_SEG_OPTS_MSS (u8_t)0x01U /* Include MSS option. */ 00292 #define TF_SEG_OPTS_TS (u8_t)0x02U /* Include timestamp option. */ 00293 #define TF_SEG_DATA_CHECKSUMMED (u8_t)0x04U /* ALL data (not the header) is 00294 checksummed into 'chksum' */ 00295 struct tcp_hdr *tcphdr; /* the TCP header */ 00296 }; 00297 00298 #define LWIP_TCP_OPT_LENGTH(flags) \ 00299 (flags & TF_SEG_OPTS_MSS ? 4 : 0) + \ 00300 (flags & TF_SEG_OPTS_TS ? 12 : 0) 00301 00302 /** This returns a TCP header option for MSS in an u32_t */ 00303 #define TCP_BUILD_MSS_OPTION(mss) htonl(0x02040000 | ((mss) & 0xFFFF)) 00304 00305 /* Global variables: */ 00306 extern struct tcp_pcb *tcp_input_pcb; 00307 extern u32_t tcp_ticks; 00308 extern u8_t tcp_active_pcbs_changed; 00309 00310 /* The TCP PCB lists. */ 00311 union tcp_listen_pcbs_t { /* List of all TCP PCBs in LISTEN state. */ 00312 struct tcp_pcb_listen *listen_pcbs; 00313 struct tcp_pcb *pcbs; 00314 }; 00315 extern struct tcp_pcb *tcp_bound_pcbs; 00316 extern union tcp_listen_pcbs_t tcp_listen_pcbs; 00317 extern struct tcp_pcb *tcp_active_pcbs; /* List of all TCP PCBs that are in a 00318 state in which they accept or send 00319 data. */ 00320 extern struct tcp_pcb *tcp_tw_pcbs; /* List of all TCP PCBs in TIME-WAIT. */ 00321 00322 extern struct tcp_pcb *tcp_tmp_pcb; /* Only used for temporary storage. */ 00323 00324 /* Axioms about the above lists: 00325 1) Every TCP PCB that is not CLOSED is in one of the lists. 00326 2) A PCB is only in one of the lists. 00327 3) All PCBs in the tcp_listen_pcbs list is in LISTEN state. 00328 4) All PCBs in the tcp_tw_pcbs list is in TIME-WAIT state. 00329 */ 00330 /* Define two macros, TCP_REG and TCP_RMV that registers a TCP PCB 00331 with a PCB list or removes a PCB from a list, respectively. */ 00332 #ifndef TCP_DEBUG_PCB_LISTS 00333 #define TCP_DEBUG_PCB_LISTS 0 00334 #endif 00335 #if TCP_DEBUG_PCB_LISTS 00336 #define TCP_REG(pcbs, npcb) do {\ 00337 LWIP_DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %d\n", (npcb), (npcb)->local_port)); \ 00338 for(tcp_tmp_pcb = *(pcbs); \ 00339 tcp_tmp_pcb != NULL; \ 00340 tcp_tmp_pcb = tcp_tmp_pcb->next) { \ 00341 LWIP_ASSERT("TCP_REG: already registered\n", tcp_tmp_pcb != (npcb)); \ 00342 } \ 00343 LWIP_ASSERT("TCP_REG: pcb->state != CLOSED", ((pcbs) == &tcp_bound_pcbs) || ((npcb)->state != CLOSED)); \ 00344 (npcb)->next = *(pcbs); \ 00345 LWIP_ASSERT("TCP_REG: npcb->next != npcb", (npcb)->next != (npcb)); \ 00346 *(pcbs) = (npcb); \ 00347 LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \ 00348 tcp_timer_needed(); \ 00349 } while(0) 00350 #define TCP_RMV(pcbs, npcb) do { \ 00351 LWIP_ASSERT("TCP_RMV: pcbs != NULL", *(pcbs) != NULL); \ 00352 LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removing %p from %p\n", (npcb), *(pcbs))); \ 00353 if(*(pcbs) == (npcb)) { \ 00354 *(pcbs) = (*pcbs)->next; \ 00355 } else for(tcp_tmp_pcb = *(pcbs); tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \ 00356 if(tcp_tmp_pcb->next == (npcb)) { \ 00357 tcp_tmp_pcb->next = (npcb)->next; \ 00358 break; \ 00359 } \ 00360 } \ 00361 (npcb)->next = NULL; \ 00362 LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \ 00363 LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", (npcb), *(pcbs))); \ 00364 } while(0) 00365 00366 #else /* LWIP_DEBUG */ 00367 00368 #define TCP_REG(pcbs, npcb) \ 00369 do { \ 00370 (npcb)->next = *pcbs; \ 00371 *(pcbs) = (npcb); \ 00372 tcp_timer_needed(); \ 00373 } while (0) 00374 00375 #define TCP_RMV(pcbs, npcb) \ 00376 do { \ 00377 if(*(pcbs) == (npcb)) { \ 00378 (*(pcbs)) = (*pcbs)->next; \ 00379 } \ 00380 else { \ 00381 for(tcp_tmp_pcb = *pcbs; \ 00382 tcp_tmp_pcb != NULL; \ 00383 tcp_tmp_pcb = tcp_tmp_pcb->next) { \ 00384 if(tcp_tmp_pcb->next == (npcb)) { \ 00385 tcp_tmp_pcb->next = (npcb)->next; \ 00386 break; \ 00387 } \ 00388 } \ 00389 } \ 00390 (npcb)->next = NULL; \ 00391 } while(0) 00392 00393 #endif /* LWIP_DEBUG */ 00394 00395 #define TCP_REG_ACTIVE(npcb) \ 00396 do { \ 00397 TCP_REG(&tcp_active_pcbs, npcb); \ 00398 tcp_active_pcbs_changed = 1; \ 00399 } while (0) 00400 00401 #define TCP_RMV_ACTIVE(npcb) \ 00402 do { \ 00403 TCP_RMV(&tcp_active_pcbs, npcb); \ 00404 tcp_active_pcbs_changed = 1; \ 00405 } while (0) 00406 00407 #define TCP_PCB_REMOVE_ACTIVE(pcb) \ 00408 do { \ 00409 tcp_pcb_remove(&tcp_active_pcbs, pcb); \ 00410 tcp_active_pcbs_changed = 1; \ 00411 } while (0) 00412 00413 00414 /* Internal functions: */ 00415 struct tcp_pcb *tcp_pcb_copy(struct tcp_pcb *pcb); 00416 void tcp_pcb_purge(struct tcp_pcb *pcb); 00417 void tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb); 00418 00419 void tcp_segs_free(struct tcp_seg *seg); 00420 void tcp_seg_free(struct tcp_seg *seg); 00421 struct tcp_seg *tcp_seg_copy(struct tcp_seg *seg); 00422 00423 #define tcp_ack(pcb) \ 00424 do { \ 00425 if((pcb)->flags & TF_ACK_DELAY) { \ 00426 (pcb)->flags &= ~TF_ACK_DELAY; \ 00427 (pcb)->flags |= TF_ACK_NOW; \ 00428 } \ 00429 else { \ 00430 (pcb)->flags |= TF_ACK_DELAY; \ 00431 } \ 00432 } while (0) 00433 00434 #define tcp_ack_now(pcb) \ 00435 do { \ 00436 (pcb)->flags |= TF_ACK_NOW; \ 00437 } while (0) 00438 00439 err_t tcp_send_fin(struct tcp_pcb *pcb); 00440 err_t tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags); 00441 00442 void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg); 00443 00444 void tcp_rst(u32_t seqno, u32_t ackno, 00445 ip_addr_t *local_ip, ip_addr_t *remote_ip, 00446 u16_t local_port, u16_t remote_port); 00447 00448 u32_t tcp_next_iss(void); 00449 00450 void tcp_keepalive(struct tcp_pcb *pcb); 00451 void tcp_zero_window_probe(struct tcp_pcb *pcb); 00452 00453 #if TCP_CALCULATE_EFF_SEND_MSS 00454 u16_t tcp_eff_send_mss(u16_t sendmss, ip_addr_t *addr); 00455 #endif /* TCP_CALCULATE_EFF_SEND_MSS */ 00456 00457 #if LWIP_CALLBACK_API 00458 err_t tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err); 00459 #endif /* LWIP_CALLBACK_API */ 00460 00461 #if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG 00462 void tcp_debug_print(struct tcp_hdr *tcphdr); 00463 void tcp_debug_print_flags(u8_t flags); 00464 void tcp_debug_print_state(enum tcp_state s); 00465 void tcp_debug_print_pcbs(void); 00466 s16_t tcp_pcbs_sane(void); 00467 #else 00468 # define tcp_debug_print(tcphdr) 00469 # define tcp_debug_print_flags(flags) 00470 # define tcp_debug_print_state(s) 00471 # define tcp_debug_print_pcbs() 00472 # define tcp_pcbs_sane() 1 00473 #endif /* TCP_DEBUG */ 00474 00475 /** External function (implemented in timers.c), called when TCP detects 00476 * that a timer is needed (i.e. active- or time-wait-pcb found). */ 00477 void tcp_timer_needed(void); 00478 00479 00480 #ifdef __cplusplus 00481 } 00482 #endif 00483 00484 #endif /* LWIP_TCP */ 00485 00486 #endif /* __LWIP_TCP_H__ */
Generated on Tue Jul 12 2022 21:19:02 by
1.7.2
