00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
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
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
00051
00052
00053 void tcp_init (void);
00054 void tcp_tmr (void);
00055
00056
00057
00058
00059 void tcp_slowtmr (void);
00060 void tcp_fasttmr (void);
00061
00062
00063
00064 void tcp_input (struct pbuf *p, struct netif *inp);
00065
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
00077
00078
00079
00080
00081
00082
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
00098 #if 0
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
00114 #define TCP_HLEN 20
00115
00116 #ifndef TCP_TMR_INTERVAL
00117 #define TCP_TMR_INTERVAL 250
00118 #endif
00119
00120 #ifndef TCP_FAST_INTERVAL
00121 #define TCP_FAST_INTERVAL TCP_TMR_INTERVAL
00122 #endif
00123
00124 #ifndef TCP_SLOW_INTERVAL
00125 #define TCP_SLOW_INTERVAL (2*TCP_TMR_INTERVAL)
00126 #endif
00127
00128 #define TCP_FIN_WAIT_TIMEOUT 20000
00129 #define TCP_SYN_RCVD_TIMEOUT 20000
00130
00131 #define TCP_OOSEQ_TIMEOUT 6U
00132
00133 #ifndef TCP_MSL
00134 #define TCP_MSL 60000UL
00135 #endif
00136
00137
00138 #ifndef TCP_KEEPIDLE_DEFAULT
00139 #define TCP_KEEPIDLE_DEFAULT 7200000UL
00140 #endif
00141
00142 #ifndef TCP_KEEPINTVL_DEFAULT
00143 #define TCP_KEEPINTVL_DEFAULT 75000UL
00144 #endif
00145
00146 #ifndef TCP_KEEPCNT_DEFAULT
00147 #define TCP_KEEPCNT_DEFAULT 9U
00148 #endif
00149
00150 #define TCP_MAXIDLE TCP_KEEPCNT_DEFAULT * TCP_KEEPINTVL_DEFAULT
00151
00152
00153
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
00187
00188 #define TF_RESET (u8_t)0x08U
00189 #define TF_CLOSED (u8_t)0x10U
00190 #define TF_GOT_FIN (u8_t)0x20U
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
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
00265
00266
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
00274 #define TCP_CHECKSUM_ON_COPY (LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_TCP)
00275
00276
00277 struct tcp_seg {
00278 struct tcp_seg *next;
00279 struct pbuf *p;
00280 u16_t len;
00281 #if TCP_OVERSIZE_DBGCHECK
00282 u16_t oversize_left;
00283
00284
00285 #endif
00286 #if TCP_CHECKSUM_ON_COPY
00287 u16_t chksum;
00288 u8_t chksum_swapped;
00289 #endif
00290 u8_t flags;
00291 #define TF_SEG_OPTS_MSS (u8_t)0x01U
00292 #define TF_SEG_OPTS_TS (u8_t)0x02U
00293 #define TF_SEG_DATA_CHECKSUMMED (u8_t)0x04U
00294
00295 struct tcp_hdr *tcphdr;
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
00303 #define TCP_BUILD_MSS_OPTION(mss) htonl(0x02040000 | ((mss) & 0xFFFF))
00304
00305
00306 extern struct tcp_pcb *tcp_input_pcb;
00307 extern u32_t tcp_ticks;
00308 extern u8_t tcp_active_pcbs_changed;
00309
00310
00311 union tcp_listen_pcbs_t {
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;
00318
00319
00320 extern struct tcp_pcb *tcp_tw_pcbs;
00321
00322 extern struct tcp_pcb *tcp_tmp_pcb;
00323
00324
00325
00326
00327
00328
00329
00330
00331
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
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
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
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
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
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
00474
00475
00476
00477 void tcp_timer_needed(void);
00478
00479
00480 #ifdef __cplusplus
00481 }
00482 #endif
00483
00484 #endif
00485
00486 #endif