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_H__
00033 #define __LWIP_TCP_H__
00034
00035 #include "lwip/sys.h"
00036 #include "lwip/mem.h"
00037
00038 #include "lwip/pbuf.h"
00039 #include "lwip/opt.h"
00040 #include "lwip/ip.h"
00041 #include "lwip/icmp.h"
00042
00043 #include "lwip/sys.h"
00044
00045 #include "lwip/err.h"
00046
00047 struct tcp_pcb;
00048
00049
00050
00051
00052 void tcp_init (void);
00053
00054 void tcp_tmr (void);
00055
00056
00057
00058 struct tcp_pcb * tcp_new (void);
00059 struct tcp_pcb * tcp_alloc (u8_t prio);
00060
00061 void tcp_arg (struct tcp_pcb *pcb, void *arg);
00062 void tcp_accept (struct tcp_pcb *pcb,
00063 err_t (* accept)(void *arg, struct tcp_pcb *newpcb,
00064 err_t err));
00065 void tcp_recv (struct tcp_pcb *pcb,
00066 err_t (* recv)(void *arg, struct tcp_pcb *tpcb,
00067 struct pbuf *p, err_t err));
00068 void tcp_sent (struct tcp_pcb *pcb,
00069 err_t (* sent)(void *arg, struct tcp_pcb *tpcb,
00070 u16_t len));
00071 void tcp_poll (struct tcp_pcb *pcb,
00072 err_t (* poll)(void *arg, struct tcp_pcb *tpcb),
00073 u8_t interval);
00074 void tcp_err (struct tcp_pcb *pcb,
00075 void (* err)(void *arg, err_t err));
00076
00077 #define tcp_mss(pcb) ((pcb)->mss)
00078 #define tcp_sndbuf(pcb) ((pcb)->snd_buf)
00079
00080 void tcp_recved (struct tcp_pcb *pcb, u16_t len);
00081 err_t tcp_bind (struct tcp_pcb *pcb, struct ip_addr *ipaddr,
00082 u16_t port);
00083 err_t tcp_connect (struct tcp_pcb *pcb, struct ip_addr *ipaddr,
00084 u16_t port, err_t (* connected)(void *arg,
00085 struct tcp_pcb *tpcb,
00086 err_t err));
00087 struct tcp_pcb * tcp_listen (struct tcp_pcb *pcb);
00088 void tcp_abort (struct tcp_pcb *pcb);
00089 err_t tcp_close (struct tcp_pcb *pcb);
00090 err_t tcp_write (struct tcp_pcb *pcb, const void *dataptr, u16_t len,
00091 u8_t copy);
00092
00093 void tcp_setprio (struct tcp_pcb *pcb, u8_t prio);
00094
00095 #define TCP_PRIO_MIN 1
00096 #define TCP_PRIO_NORMAL 64
00097 #define TCP_PRIO_MAX 127
00098
00099
00100
00101 void tcp_slowtmr (void);
00102 void tcp_fasttmr (void);
00103
00104
00105
00106 void tcp_input (struct pbuf *p, struct netif *inp);
00107
00108 err_t tcp_output (struct tcp_pcb *pcb);
00109 void tcp_rexmit (struct tcp_pcb *pcb);
00110
00111
00112
00113 #define TCP_SEQ_LT(a,b) ((s32_t)((a)-(b)) < 0)
00114 #define TCP_SEQ_LEQ(a,b) ((s32_t)((a)-(b)) <= 0)
00115 #define TCP_SEQ_GT(a,b) ((s32_t)((a)-(b)) > 0)
00116 #define TCP_SEQ_GEQ(a,b) ((s32_t)((a)-(b)) >= 0)
00117
00118 #define TCP_FIN 0x01
00119 #define TCP_SYN 0x02
00120 #define TCP_RST 0x04
00121 #define TCP_PSH 0x08
00122 #define TCP_ACK 0x10
00123 #define TCP_URG 0x20
00124
00125 #define TCP_FLAGS 0x3f
00126
00127
00128 #define TCP_HLEN 20
00129
00130 #ifndef TCP_TMR_INTERVAL
00131 #define TCP_TMR_INTERVAL 100
00132
00133 #endif
00134
00135 #ifndef TCP_FAST_INTERVAL
00136 #define TCP_FAST_INTERVAL 200
00137
00138 #endif
00139
00140 #ifndef TCP_SLOW_INTERVAL
00141 #define TCP_SLOW_INTERVAL 500
00142
00143 #endif
00144
00145 #define TCP_FIN_WAIT_TIMEOUT 20000
00146 #define TCP_SYN_RCVD_TIMEOUT 20000
00147
00148 #define TCP_OOSEQ_TIMEOUT 6
00149
00150 #define TCP_MSL 60000
00151
00152 #ifdef PACK_STRUCT_USE_INCLUDES
00153 # include "arch/bpstruct.h"
00154 #endif
00155 PACK_STRUCT_BEGIN
00156 struct tcp_hdr {
00157 PACK_STRUCT_FIELD(u16_t src);
00158 PACK_STRUCT_FIELD(u16_t dest);
00159 PACK_STRUCT_FIELD(u32_t seqno);
00160 PACK_STRUCT_FIELD(u32_t ackno);
00161 PACK_STRUCT_FIELD(u16_t _offset_flags);
00162 PACK_STRUCT_FIELD(u16_t wnd);
00163 PACK_STRUCT_FIELD(u16_t chksum);
00164 PACK_STRUCT_FIELD(u16_t urgp);
00165 } PACK_STRUCT_STRUCT;
00166 PACK_STRUCT_END
00167 #ifdef PACK_STRUCT_USE_INCLUDES
00168 # include "arch/epstruct.h"
00169 #endif
00170
00171 #define TCPH_OFFSET(hdr) (ntohs((hdr)->_offset_flags) >> 8)
00172 #define TCPH_FLAGS(hdr) (ntohs((hdr)->_offset_flags) & 0xff)
00173
00174 #define TCPH_OFFSET_SET(hdr, offset) (hdr)->_offset_flags = htons(((offset) << 8) | TCPH_FLAGS(hdr))
00175 #define TCPH_FLAGS_SET(hdr, flags) (hdr)->_offset_flags = htons((TCPH_OFFSET(hdr) << 8) | (flags))
00176
00177 #define TCP_TCPLEN(seg) ((seg)->len + ((TCPH_FLAGS((seg)->tcphdr) & TCP_FIN || \
00178 TCPH_FLAGS((seg)->tcphdr) & TCP_SYN)? 1: 0))
00179
00180 enum tcp_state {
00181 CLOSED = 0,
00182 LISTEN = 1,
00183 SYN_SENT = 2,
00184 SYN_RCVD = 3,
00185 ESTABLISHED = 4,
00186 FIN_WAIT_1 = 5,
00187 FIN_WAIT_2 = 6,
00188 CLOSE_WAIT = 7,
00189 CLOSING = 8,
00190 LAST_ACK = 9,
00191 TIME_WAIT = 10
00192 };
00193
00194
00195
00196 struct tcp_pcb {
00197 struct tcp_pcb *next;
00198 u8_t prio;
00199 void *callback_arg;
00200
00201 struct ip_addr local_ip;
00202 u16_t local_port;
00203 enum tcp_state state;
00204
00205 struct ip_addr remote_ip;
00206 u16_t remote_port;
00207
00208
00209 u32_t rcv_nxt;
00210 u16_t rcv_wnd;
00211
00212
00213
00214 u32_t tmr;
00215 u8_t polltmr, pollinterval;
00216
00217
00218 u16_t rtime;
00219
00220 u16_t mss;
00221
00222 u8_t flags;
00223 #define TF_ACK_DELAY 0x01U
00224 #define TF_ACK_NOW 0x02U
00225 #define TF_INFR 0x04U
00226 #define TF_RESET 0x08U
00227 #define TF_CLOSED 0x10U
00228 #define TF_GOT_FIN 0x20U
00229
00230
00231 u16_t rttest;
00232 u32_t rtseq;
00233 s16_t sa, sv;
00234
00235 u16_t rto;
00236 u8_t nrtx;
00237
00238
00239 u32_t lastack;
00240 u8_t dupacks;
00241
00242
00243 u16_t cwnd;
00244 u16_t ssthresh;
00245
00246
00247 u32_t snd_nxt,
00248 snd_max,
00249 snd_wnd,
00250 snd_wl1, snd_wl2,
00251
00252 snd_lbb;
00253
00254 u16_t acked;
00255
00256 u16_t snd_buf;
00257 u8_t snd_queuelen;
00258
00259
00260
00261 struct tcp_seg *unsent;
00262 struct tcp_seg *unacked;
00263 #if TCP_QUEUE_OOSEQ
00264 struct tcp_seg *ooseq;
00265 #endif
00266
00267 #if LWIP_CALLBACK_API
00268
00269 err_t (* sent)(void *arg, struct tcp_pcb *pcb, u16_t space);
00270
00271
00272 err_t (* recv)(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);
00273
00274
00275 err_t (* connected)(void *arg, struct tcp_pcb *pcb, err_t err);
00276
00277
00278 err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err);
00279
00280
00281 err_t (* poll)(void *arg, struct tcp_pcb *pcb);
00282
00283
00284 void (* errf)(void *arg, err_t err);
00285 #endif
00286 };
00287
00288 struct tcp_pcb_listen {
00289 struct tcp_pcb_listen *next;
00290 u8_t prio;
00291 void *callback_arg;
00292
00293 struct ip_addr local_ip;
00294 u16_t local_port;
00295
00296
00297
00298
00299 enum tcp_state state;
00300
00301 #if LWIP_CALLBACK_API
00302
00303 err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err);
00304 #endif
00305 };
00306
00307 #if LWIP_EVENT_API
00308
00309 enum lwip_event {
00310 LWIP_EVENT_ACCEPT,
00311 LWIP_EVENT_SENT,
00312 LWIP_EVENT_RECV,
00313 LWIP_EVENT_CONNECTED,
00314 LWIP_EVENT_POLL,
00315 LWIP_EVENT_ERR
00316 };
00317
00318 err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb,
00319 enum lwip_event,
00320 struct pbuf *p,
00321 u16_t size,
00322 err_t err);
00323
00324 #define TCP_EVENT_ACCEPT(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
00325 LWIP_EVENT_ACCEPT, NULL, 0, err)
00326 #define TCP_EVENT_SENT(pcb,space,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
00327 LWIP_EVENT_SENT, NULL, space, ERR_OK)
00328 #define TCP_EVENT_RECV(pcb,p,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
00329 LWIP_EVENT_RECV, (p), 0, (err))
00330 #define TCP_EVENT_CONNECTED(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
00331 LWIP_EVENT_CONNECTED, NULL, 0, (err))
00332 #define TCP_EVENT_POLL(pcb,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
00333 LWIP_EVENT_POLL, NULL, 0, ERR_OK)
00334 #define TCP_EVENT_ERR(errf,arg,err) lwip_tcp_event((arg), NULL, \
00335 LWIP_EVENT_ERR, NULL, 0, (err))
00336 #else
00337 #define TCP_EVENT_ACCEPT(pcb,err,ret) \
00338 if((pcb)->accept != NULL) \
00339 (ret = (pcb)->accept((pcb)->callback_arg,(pcb),(err)))
00340 #define TCP_EVENT_SENT(pcb,space,ret) \
00341 if((pcb)->sent != NULL) \
00342 (ret = (pcb)->sent((pcb)->callback_arg,(pcb),(space)))
00343 #define TCP_EVENT_RECV(pcb,p,err,ret) \
00344 if((pcb)->recv != NULL) \
00345 { ret = (pcb)->recv((pcb)->callback_arg,(pcb),(p),(err)); } else { \
00346 pbuf_free(p); }
00347 #define TCP_EVENT_CONNECTED(pcb,err,ret) \
00348 if((pcb)->connected != NULL) \
00349 (ret = (pcb)->connected((pcb)->callback_arg,(pcb),(err)))
00350 #define TCP_EVENT_POLL(pcb,ret) \
00351 if((pcb)->poll != NULL) \
00352 (ret = (pcb)->poll((pcb)->callback_arg,(pcb)))
00353 #define TCP_EVENT_ERR(errf,arg,err) \
00354 if((errf) != NULL) \
00355 (errf)((arg),(err))
00356 #endif
00357
00358
00359 struct tcp_seg {
00360 struct tcp_seg *next;
00361 struct pbuf *p;
00362 void *dataptr;
00363 u16_t len;
00364 struct tcp_hdr *tcphdr;
00365 };
00366
00367
00368 struct tcp_pcb *tcp_pcb_copy(struct tcp_pcb *pcb);
00369 void tcp_pcb_purge(struct tcp_pcb *pcb);
00370 void tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb);
00371
00372 u8_t tcp_segs_free(struct tcp_seg *seg);
00373 u8_t tcp_seg_free(struct tcp_seg *seg);
00374 struct tcp_seg *tcp_seg_copy(struct tcp_seg *seg);
00375
00376 #define tcp_ack(pcb) if((pcb)->flags & TF_ACK_DELAY) { \
00377 (pcb)->flags &= ~TF_ACK_DELAY; \
00378 (pcb)->flags |= TF_ACK_NOW; \
00379 tcp_output(pcb); \
00380 } else { \
00381 (pcb)->flags |= TF_ACK_DELAY; \
00382 }
00383
00384 #define tcp_ack_now(pcb) (pcb)->flags |= TF_ACK_NOW; \
00385 tcp_output(pcb)
00386
00387 err_t tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags);
00388 err_t tcp_enqueue(struct tcp_pcb *pcb, void *dataptr, u16_t len,
00389 u8_t flags, u8_t copy,
00390 u8_t *optdata, u8_t optlen);
00391
00392 void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg);
00393
00394 void tcp_rst(u32_t seqno, u32_t ackno,
00395 struct ip_addr *local_ip, struct ip_addr *remote_ip,
00396 u16_t local_port, u16_t remote_port);
00397
00398 u32_t tcp_next_iss(void);
00399
00400 extern struct tcp_pcb *tcp_input_pcb;
00401 extern u32_t tcp_ticks;
00402
00403 #if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG
00404 void tcp_debug_print(struct tcp_hdr *tcphdr);
00405 void tcp_debug_print_flags(u8_t flags);
00406 void tcp_debug_print_state(enum tcp_state s);
00407 void tcp_debug_print_pcbs(void);
00408 int tcp_pcbs_sane(void);
00409 #else
00410 #define tcp_pcbs_sane() 1
00411 #endif
00412
00413 #if NO_SYS
00414 #define tcp_timer_needed()
00415 #else
00416 void tcp_timer_needed(void);
00417 #endif
00418
00419
00420 extern struct tcp_pcb_listen *tcp_listen_pcbs;
00421 extern struct tcp_pcb *tcp_active_pcbs;
00422
00423
00424 extern struct tcp_pcb *tcp_tw_pcbs;
00425
00426 extern struct tcp_pcb *tcp_tmp_pcb;
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437 #if 0
00438 #define TCP_REG(pcbs, npcb) do {\
00439 DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %d\n", npcb, npcb->local_port)); \
00440 for(tcp_tmp_pcb = *pcbs; \
00441 tcp_tmp_pcb != NULL; \
00442 tcp_tmp_pcb = tcp_tmp_pcb->next) { \
00443 LWIP_ASSERT("TCP_REG: already registered\n", tcp_tmp_pcb != npcb); \
00444 } \
00445 LWIP_ASSERT("TCP_REG: pcb->state != CLOSED", npcb->state != CLOSED); \
00446 npcb->next = *pcbs; \
00447 LWIP_ASSERT("TCP_REG: npcb->next != npcb", npcb->next != npcb); \
00448 *(pcbs) = npcb; \
00449 LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \
00450 tcp_timer_needed(); \
00451 } while(0)
00452 #define TCP_RMV(pcbs, npcb) do { \
00453 LWIP_ASSERT("TCP_RMV: pcbs != NULL", *pcbs != NULL); \
00454 DEBUGF(TCP_DEBUG, ("TCP_RMV: removing %p from %p\n", npcb, *pcbs)); \
00455 if(*pcbs == npcb) { \
00456 *pcbs = (*pcbs)->next; \
00457 } else for(tcp_tmp_pcb = *pcbs; tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \
00458 if(tcp_tmp_pcb->next != NULL && tcp_tmp_pcb->next == npcb) { \
00459 tcp_tmp_pcb->next = npcb->next; \
00460 break; \
00461 } \
00462 } \
00463 npcb->next = NULL; \
00464 LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \
00465 DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", npcb, *pcbs)); \
00466 } while(0)
00467
00468 #else
00469 #define TCP_REG(pcbs, npcb) do { \
00470 npcb->next = *pcbs; \
00471 *(pcbs) = npcb; \
00472 tcp_timer_needed(); \
00473 } while(0)
00474 #define TCP_RMV(pcbs, npcb) do { \
00475 if(*(pcbs) == npcb) { \
00476 (*(pcbs)) = (*pcbs)->next; \
00477 } else for(tcp_tmp_pcb = *pcbs; tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \
00478 if(tcp_tmp_pcb->next != NULL && tcp_tmp_pcb->next == npcb) { \
00479 tcp_tmp_pcb->next = npcb->next; \
00480 break; \
00481 } \
00482 } \
00483 npcb->next = NULL; \
00484 } while(0)
00485 #endif
00486 #endif
00487
00488
00489