tcp.h
上传用户:yyhongfa
上传日期:2013-01-18
资源大小:267k
文件大小:20k
开发平台:

C/C++

  1. /*
  2.  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
  3.  * All rights reserved. 
  4.  * 
  5.  * Redistribution and use in source and binary forms, with or without modification, 
  6.  * are permitted provided that the following conditions are met:
  7.  *
  8.  * 1. Redistributions of source code must retain the above copyright notice,
  9.  *    this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright notice,
  11.  *    this list of conditions and the following disclaimer in the documentation
  12.  *    and/or other materials provided with the distribution.
  13.  * 3. The name of the author may not be used to endorse or promote products
  14.  *    derived from this software without specific prior written permission. 
  15.  *
  16.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
  17.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
  18.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
  19.  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
  20.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
  21.  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
  22.  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
  23.  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
  24.  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
  25.  * OF SUCH DAMAGE.
  26.  *
  27.  * This file is part of the lwIP TCP/IP stack.
  28.  * 
  29.  * Author: Adam Dunkels <adam@sics.se>
  30.  *
  31.  */
  32. #ifndef __LWIP_TCP_H__
  33. #define __LWIP_TCP_H__
  34. #include "lwip/sys.h"
  35. #include "lwip/mem.h"
  36. #include "lwip/pbuf.h"
  37. #include "lwip/opt.h"
  38. #include "lwip/ip.h"
  39. #include "lwip/icmp.h"
  40. #include "lwip/err.h"
  41. struct tcp_pcb;
  42. /* Functions for interfacing with TCP: */
  43. /* Lower layer interface to TCP: */
  44. void             tcp_init    (void);  /* Must be called first to
  45.            initialize TCP. */
  46. void             tcp_tmr     (void);  /* Must be called every
  47.            TCP_TMR_INTERVAL
  48.            ms. (Typically 250 ms). */
  49. /* Application program's interface: */
  50. struct tcp_pcb * tcp_new     (void);
  51. struct tcp_pcb * tcp_alloc   (u8_t prio);
  52. void             tcp_arg     (struct tcp_pcb *pcb, void *arg);
  53. void             tcp_accept  (struct tcp_pcb *pcb,
  54.             err_t (* accept)(void *arg, struct tcp_pcb *newpcb,
  55.                  err_t err));
  56. void             tcp_recv    (struct tcp_pcb *pcb,
  57.             err_t (* recv)(void *arg, struct tcp_pcb *tpcb,
  58.           struct pbuf *p, err_t err));
  59. void             tcp_sent    (struct tcp_pcb *pcb,
  60.             err_t (* sent)(void *arg, struct tcp_pcb *tpcb,
  61.                u16_t len));
  62. void             tcp_poll    (struct tcp_pcb *pcb,
  63.             err_t (* poll)(void *arg, struct tcp_pcb *tpcb),
  64.             u8_t interval);
  65. void             tcp_err     (struct tcp_pcb *pcb,
  66.             void (* err)(void *arg, err_t err));
  67. #define          tcp_mss(pcb)      ((pcb)->mss)
  68. #define          tcp_sndbuf(pcb)   ((pcb)->snd_buf)
  69. void             tcp_recved  (struct tcp_pcb *pcb, u16_t len);
  70. err_t            tcp_bind    (struct tcp_pcb *pcb, struct ip_addr *ipaddr,
  71.             u16_t port);
  72. err_t            tcp_connect (struct tcp_pcb *pcb, struct ip_addr *ipaddr,
  73.             u16_t port, err_t (* connected)(void *arg,
  74.                     struct tcp_pcb *tpcb,
  75.                     err_t err));
  76. struct tcp_pcb * tcp_listen  (struct tcp_pcb *pcb);
  77. void             tcp_abort   (struct tcp_pcb *pcb);
  78. err_t            tcp_close   (struct tcp_pcb *pcb);
  79. err_t            tcp_write   (struct tcp_pcb *pcb, const void *dataptr, u16_t len,
  80.             u8_t copy);
  81. void             tcp_setprio (struct tcp_pcb *pcb, u8_t prio);
  82. #define TCP_PRIO_MIN    1
  83. #define TCP_PRIO_NORMAL 64
  84. #define TCP_PRIO_MAX    127
  85. /* It is also possible to call these two functions at the right
  86.    intervals (instead of calling tcp_tmr()). */
  87. void             tcp_slowtmr (void);
  88. void             tcp_fasttmr (void);
  89. /* Only used by IP to pass a TCP segment to TCP: */
  90. void             tcp_input   (struct pbuf *p, struct netif *inp);
  91. /* Used within the TCP code only: */
  92. err_t            tcp_output  (struct tcp_pcb *pcb);
  93. void             tcp_rexmit  (struct tcp_pcb *pcb);
  94. void             tcp_rexmit_rto  (struct tcp_pcb *pcb);
  95. #define TCP_SEQ_LT(a,b)     ((s32_t)((a)-(b)) < 0)
  96. #define TCP_SEQ_LEQ(a,b)    ((s32_t)((a)-(b)) <= 0)
  97. #define TCP_SEQ_GT(a,b)     ((s32_t)((a)-(b)) > 0)
  98. #define TCP_SEQ_GEQ(a,b)    ((s32_t)((a)-(b)) >= 0)
  99. /* is b<=a<=c? */
  100. #if 0 /* see bug #10548 */
  101. #define TCP_SEQ_BETWEEN(a,b,c) ((c)-(b) >= (a)-(b))
  102. #endif
  103. #define TCP_SEQ_BETWEEN(a,b,c) (TCP_SEQ_GEQ(a,b) && TCP_SEQ_LEQ(a,c))
  104. #define TCP_FIN 0x01U
  105. #define TCP_SYN 0x02U
  106. #define TCP_RST 0x04U
  107. #define TCP_PSH 0x08U
  108. #define TCP_ACK 0x10U
  109. #define TCP_URG 0x20U
  110. #define TCP_ECE 0x40U
  111. #define TCP_CWR 0x80U
  112. #define TCP_FLAGS 0x3fU
  113. /* Length of the TCP header, excluding options. */
  114. #define TCP_HLEN 20
  115. #ifndef TCP_TMR_INTERVAL
  116. #define TCP_TMR_INTERVAL       250  /* The TCP timer interval in milliseconds. */
  117. //#define TCP_TMR_INTERVAL       1000
  118. #endif /* TCP_TMR_INTERVAL */
  119. #ifndef TCP_FAST_INTERVAL
  120. #define TCP_FAST_INTERVAL      TCP_TMR_INTERVAL /* the fine grained timeout in
  121.                                        milliseconds */
  122. #endif /* TCP_FAST_INTERVAL */
  123. #ifndef TCP_SLOW_INTERVAL
  124. #define TCP_SLOW_INTERVAL      (2*TCP_TMR_INTERVAL)  /* the coarse grained timeout in
  125.                                        milliseconds */
  126. #endif /* TCP_SLOW_INTERVAL */
  127. #define TCP_FIN_WAIT_TIMEOUT 20000 /* milliseconds */
  128. #define TCP_SYN_RCVD_TIMEOUT 20000 /* milliseconds */
  129. #define TCP_OOSEQ_TIMEOUT        6 /* x RTO */
  130. #define TCP_MSL 60000  /* The maximum segment lifetime in microseconds */
  131. /*
  132.  * User-settable options (used with setsockopt).
  133.  */
  134. #define TCP_NODELAY    0x01    /* don't delay send to coalesce packets */
  135. #define TCP_KEEPALIVE  0x02    /* send KEEPALIVE probes when idle for pcb->keepalive miliseconds */
  136. /* Keepalive values */
  137. #define  TCP_KEEPDEFAULT   7200000                       /* KEEPALIVE timer in miliseconds */
  138. #define  TCP_KEEPINTVL     75000                         /* Time between KEEPALIVE probes in miliseconds */
  139. #define  TCP_KEEPCNT       9                             /* Counter for KEEPALIVE probes */
  140. #define  TCP_MAXIDLE       TCP_KEEPCNT * TCP_KEEPINTVL   /* Maximum KEEPALIVE probe time */
  141. #ifdef PACK_STRUCT_USE_INCLUDES
  142. #  include "arch/bpstruct.h"
  143. #endif
  144. PACK_STRUCT_BEGIN
  145. struct tcp_hdr {
  146.   PACK_STRUCT_FIELD(u16_t src);
  147.   PACK_STRUCT_FIELD(u16_t dest);
  148.   PACK_STRUCT_FIELD(u32_t seqno);
  149.   PACK_STRUCT_FIELD(u32_t ackno);
  150.   PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags);
  151.   PACK_STRUCT_FIELD(u16_t wnd);
  152.   PACK_STRUCT_FIELD(u16_t chksum);
  153.   PACK_STRUCT_FIELD(u16_t urgp);
  154. } PACK_STRUCT_STRUCT;
  155. PACK_STRUCT_END
  156. #ifdef PACK_STRUCT_USE_INCLUDES
  157. #  include "arch/epstruct.h"
  158. #endif
  159. #define TCPH_OFFSET(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 8)
  160. #define TCPH_HDRLEN(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 12)
  161. #define TCPH_FLAGS(phdr)  (ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS)
  162. #define TCPH_OFFSET_SET(phdr, offset) (phdr)->_hdrlen_rsvd_flags = htons(((offset) << 8) | TCPH_FLAGS(phdr))
  163. #define TCPH_HDRLEN_SET(phdr, len) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | TCPH_FLAGS(phdr))
  164. #define TCPH_FLAGS_SET(phdr, flags) (phdr)->_hdrlen_rsvd_flags = htons((ntohs((phdr)->_hdrlen_rsvd_flags) & ~TCP_FLAGS) | (flags))
  165. #define TCPH_SET_FLAG(phdr, flags ) (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (flags))
  166. #define TCPH_UNSET_FLAG(phdr, flags) (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (TCPH_FLAGS(phdr) & ~(flags)) )
  167. #define TCP_TCPLEN(seg) ((seg)->len + ((TCPH_FLAGS((seg)->tcphdr) & TCP_FIN || 
  168.           TCPH_FLAGS((seg)->tcphdr) & TCP_SYN)? 1: 0))
  169. enum tcp_state {
  170.   CLOSED      = 0,
  171.   LISTEN      = 1,
  172.   SYN_SENT    = 2,
  173.   SYN_RCVD    = 3,
  174.   ESTABLISHED = 4,
  175.   FIN_WAIT_1  = 5,
  176.   FIN_WAIT_2  = 6,
  177.   CLOSE_WAIT  = 7,
  178.   CLOSING     = 8,
  179.   LAST_ACK    = 9,
  180.   TIME_WAIT   = 10
  181. };
  182. /* the TCP protocol control block */
  183. struct tcp_pcb {
  184. /** common PCB members */
  185.   IP_PCB;
  186. /** protocol specific PCB members */
  187.   struct tcp_pcb *next; /* for the linked list */
  188.   enum tcp_state state; /* TCP state */
  189.   u8_t prio;
  190.   void *callback_arg;
  191.   u16_t local_port;
  192.   u16_t remote_port;
  193.   
  194.   u8_t flags;
  195. #define TF_ACK_DELAY (u8_t)0x01U   /* Delayed ACK. */
  196. #define TF_ACK_NOW   (u8_t)0x02U   /* Immediate ACK. */
  197. #define TF_INFR      (u8_t)0x04U   /* In fast recovery. */
  198. #define TF_RESET     (u8_t)0x08U   /* Connection was reset. */
  199. #define TF_CLOSED    (u8_t)0x10U   /* Connection was sucessfully closed. */
  200. #define TF_GOT_FIN   (u8_t)0x20U   /* Connection was closed by the remote end. */
  201. #define TF_NODELAY   (u8_t)0x40U   /* Disable Nagle algorithm */
  202.   /* receiver variables */
  203.   u32_t rcv_nxt;   /* next seqno expected */
  204.   u16_t rcv_wnd;   /* receiver window */
  205.   
  206.   /* Timers */
  207.   u32_t tmr;
  208.   u8_t polltmr, pollinterval;
  209.   
  210.   /* Retransmission timer. */
  211.   u16_t rtime;
  212.   
  213.   u16_t mss;   /* maximum segment size */
  214.   
  215.   /* RTT (round trip time) estimation variables */
  216.   u32_t rttest; /* RTT estimate in 500ms ticks */
  217.   u32_t rtseq;  /* sequence number being timed */
  218.   s16_t sa, sv; /* @todo document this */
  219.   u16_t rto;    /* retransmission time-out */
  220.   u8_t nrtx;    /* number of retransmissions */
  221.   /* fast retransmit/recovery */
  222.   u32_t lastack; /* Highest acknowledged seqno. */
  223.   u8_t dupacks;
  224.   
  225.   /* congestion avoidance/control variables */
  226.   u16_t cwnd;  
  227.   u16_t ssthresh;
  228.   /* sender variables */
  229.   u32_t snd_nxt,       /* next seqno to be sent */
  230.     snd_max,       /* Highest seqno sent. */
  231.     snd_wnd,       /* sender window */
  232.     snd_wl1, snd_wl2, /* Sequence and acknowledgement numbers of last
  233.        window update. */
  234.     snd_lbb;       /* Sequence number of next byte to be buffered. */
  235.   u16_t acked;
  236.   
  237.   u16_t snd_buf;   /* Available buffer space for sending (in bytes). */
  238.   u8_t snd_queuelen; /* Available buffer space for sending (in tcp_segs). */
  239.   
  240.   
  241.   /* These are ordered by sequence number: */
  242.   struct tcp_seg *unsent;   /* Unsent (queued) segments. */
  243.   struct tcp_seg *unacked;  /* Sent but unacknowledged segments. */
  244. #if TCP_QUEUE_OOSEQ  
  245.   struct tcp_seg *ooseq;    /* Received out of sequence segments. */
  246. #endif /* TCP_QUEUE_OOSEQ */
  247. #if LWIP_CALLBACK_API
  248.   /* Function to be called when more send buffer space is available. */
  249.   err_t (* sent)(void *arg, struct tcp_pcb *pcb, u16_t space);
  250.   
  251.   /* Function to be called when (in-sequence) data has arrived. */
  252.   err_t (* recv)(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);
  253.   /* Function to be called when a connection has been set up. */
  254.   err_t (* connected)(void *arg, struct tcp_pcb *pcb, err_t err);
  255.   /* Function to call when a listener has been connected. */
  256.   err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err);
  257.   /* Function which is called periodically. */
  258.   err_t (* poll)(void *arg, struct tcp_pcb *pcb);
  259.   /* Function to be called whenever a fatal error occurs. */
  260.   void (* errf)(void *arg, err_t err);
  261. #endif /* LWIP_CALLBACK_API */
  262.   /* idle time before KEEPALIVE is sent */
  263.   u32_t keepalive;
  264.   
  265.   /* KEEPALIVE counter */
  266.   u8_t keep_cnt;
  267. };
  268. struct tcp_pcb_listen {  
  269. /* Common members of all PCB types */
  270.   IP_PCB;
  271. /* Protocol specific PCB members */
  272.   struct tcp_pcb_listen *next;   /* for the linked list */
  273.   
  274.   /* Even if state is obviously LISTEN this is here for
  275.    * field compatibility with tpc_pcb to which it is cast sometimes
  276.    * Until a cleaner solution emerges this is here.FIXME
  277.    */ 
  278.   enum tcp_state state;   /* TCP state */
  279.   u8_t prio;
  280.   void *callback_arg;
  281.   
  282.   u16_t local_port; 
  283. #if LWIP_CALLBACK_API
  284.   /* Function to call when a listener has been connected. */
  285.   err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err);
  286. #endif /* LWIP_CALLBACK_API */
  287. };
  288. #if LWIP_EVENT_API
  289. /*enum lwip_event {
  290.   LWIP_EVENT_ACCEPT,
  291.   LWIP_EVENT_SENT,
  292.   LWIP_EVENT_RECV,
  293.   LWIP_EVENT_CONNECTED,
  294.   LWIP_EVENT_POLL,
  295.   LWIP_EVENT_ERR
  296. };*/
  297. typedef enum  {
  298.   LWIP_EVENT_ACCEPT,
  299.   LWIP_EVENT_SENT,
  300.   LWIP_EVENT_RECV,
  301.   LWIP_EVENT_CONNECTED,
  302.   LWIP_EVENT_POLL,
  303.   LWIP_EVENT_ERR
  304. }LWIP_STATE;
  305. /*err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb,
  306.          enum lwip_event,
  307.          struct pbuf *p,
  308.          u16_t size,
  309.          err_t err);*/
  310.          
  311.          err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb,
  312.          LWIP_STATE lwip_event,
  313.          struct pbuf *p,
  314.          u16_t size,
  315.          err_t err);
  316. #define TCP_EVENT_ACCEPT(pcb,err,ret)    ret = lwip_tcp_event((pcb)->callback_arg, (pcb),
  317.                 LWIP_EVENT_ACCEPT, NULL, 0, err)
  318. #define TCP_EVENT_SENT(pcb,space,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),
  319.                    LWIP_EVENT_SENT, NULL, space, ERR_OK)
  320. #define TCP_EVENT_RECV(pcb,p,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),
  321.                 LWIP_EVENT_RECV, (p), 0, (err))
  322. #define TCP_EVENT_CONNECTED(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),
  323.                 LWIP_EVENT_CONNECTED, NULL, 0, (err))
  324. #define TCP_EVENT_POLL(pcb,ret)       ret = lwip_tcp_event((pcb)->callback_arg, (pcb),
  325.                 LWIP_EVENT_POLL, NULL, 0, ERR_OK)
  326. #define TCP_EVENT_ERR(errf,arg,err)  lwip_tcp_event((arg), NULL, 
  327.                 LWIP_EVENT_ERR, NULL, 0, (err))
  328. #else /* LWIP_EVENT_API */
  329. #define TCP_EVENT_ACCEPT(pcb,err,ret)     
  330.                         if((pcb)->accept != NULL) 
  331.                         (ret = (pcb)->accept((pcb)->callback_arg,(pcb),(err)))
  332. #define TCP_EVENT_SENT(pcb,space,ret) 
  333.                         if((pcb)->sent != NULL) 
  334.                         (ret = (pcb)->sent((pcb)->callback_arg,(pcb),(space)))
  335. #define TCP_EVENT_RECV(pcb,p,err,ret) 
  336.                         if((pcb)->recv != NULL) 
  337.                         { ret = (pcb)->recv((pcb)->callback_arg,(pcb),(p),(err)); } else { 
  338.                           if (p) pbuf_free(p); }
  339. #define TCP_EVENT_CONNECTED(pcb,err,ret) 
  340.                         if((pcb)->connected != NULL) 
  341.                         (ret = (pcb)->connected((pcb)->callback_arg,(pcb),(err)))
  342. #define TCP_EVENT_POLL(pcb,ret) 
  343.                         if((pcb)->poll != NULL) 
  344.                         (ret = (pcb)->poll((pcb)->callback_arg,(pcb)))
  345. #define TCP_EVENT_ERR(errf,arg,err) 
  346.                         if((errf) != NULL) 
  347.                         (errf)((arg),(err))
  348. #endif /* LWIP_EVENT_API */
  349. /* This structure represents a TCP segment on the unsent and unacked queues */
  350. struct tcp_seg {
  351.   struct tcp_seg *next;    /* used when putting segements on a queue */
  352.   struct pbuf *p;          /* buffer containing data + TCP header */
  353.   void *dataptr;           /* pointer to the TCP data in the pbuf */
  354.   u16_t len;               /* the TCP length of this segment */
  355.   struct tcp_hdr *tcphdr;  /* the TCP header */
  356. };
  357. /* Internal functions and global variables: */
  358. struct tcp_pcb *tcp_pcb_copy(struct tcp_pcb *pcb);
  359. void tcp_pcb_purge(struct tcp_pcb *pcb);
  360. void tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb);
  361. u8_t tcp_segs_free(struct tcp_seg *seg);
  362. u8_t tcp_seg_free(struct tcp_seg *seg);
  363. struct tcp_seg *tcp_seg_copy(struct tcp_seg *seg);
  364. #define tcp_ack(pcb)     if((pcb)->flags & TF_ACK_DELAY) { 
  365.                             (pcb)->flags &= ~TF_ACK_DELAY; 
  366.                             (pcb)->flags |= TF_ACK_NOW; 
  367.                             tcp_output(pcb); 
  368.                          } else { 
  369.                             (pcb)->flags |= TF_ACK_DELAY; 
  370.                          }
  371. #define tcp_ack_now(pcb) (pcb)->flags |= TF_ACK_NOW; 
  372.                          tcp_output(pcb)
  373. err_t tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags);
  374. err_t tcp_enqueue(struct tcp_pcb *pcb, void *dataptr, u16_t len,
  375.     u8_t flags, u8_t copy,
  376.                 u8_t *optdata, u8_t optlen);
  377. void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg);
  378. void tcp_rst(u32_t seqno, u32_t ackno,
  379.        struct ip_addr *local_ip, struct ip_addr *remote_ip,
  380.        u16_t local_port, u16_t remote_port);
  381. u32_t tcp_next_iss(void);
  382. void tcp_keepalive(struct tcp_pcb *pcb);
  383. extern struct tcp_pcb *tcp_input_pcb;
  384. extern u32_t tcp_ticks;
  385. #if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG
  386. void tcp_debug_print(struct tcp_hdr *tcphdr);
  387. void tcp_debug_print_flags(u8_t flags);
  388. void tcp_debug_print_state(enum tcp_state s);
  389. void tcp_debug_print_pcbs(void);
  390. int tcp_pcbs_sane(void);
  391. #else
  392. #  define tcp_debug_print(tcphdr)
  393. #  define tcp_debug_print_flags(flags)
  394. #  define tcp_debug_print_state(s)
  395. #  define tcp_debug_print_pcbs()
  396. #  define tcp_pcbs_sane() 1
  397. #endif /* TCP_DEBUG */
  398. #if NO_SYS
  399. #define tcp_timer_needed()
  400. #else
  401. void tcp_timer_needed(void);
  402. #endif
  403. /* The TCP PCB lists. */
  404. union tcp_listen_pcbs_t { /* List of all TCP PCBs in LISTEN state. */
  405. struct tcp_pcb_listen *listen_pcbs; 
  406. struct tcp_pcb *pcbs;
  407. };
  408. extern union tcp_listen_pcbs_t tcp_listen_pcbs;
  409. extern struct tcp_pcb *tcp_active_pcbs;  /* List of all TCP PCBs that are in a
  410.               state in which they accept or send
  411.               data. */
  412. extern struct tcp_pcb *tcp_tw_pcbs;      /* List of all TCP PCBs in TIME-WAIT. */
  413. extern struct tcp_pcb *tcp_tmp_pcb;      /* Only used for temporary storage. */
  414. /* Axioms about the above lists:   
  415.    1) Every TCP PCB that is not CLOSED is in one of the lists.
  416.    2) A PCB is only in one of the lists.
  417.    3) All PCBs in the tcp_listen_pcbs list is in LISTEN state.
  418.    4) All PCBs in the tcp_tw_pcbs list is in TIME-WAIT state.
  419. */
  420. /* Define two macros, TCP_REG and TCP_RMV that registers a TCP PCB
  421.    with a PCB list or removes a PCB from a list, respectively. */
  422. #if 0
  423. #define TCP_REG(pcbs, npcb) do {
  424.                             LWIP_DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %dn", npcb, npcb->local_port)); 
  425.                             for(tcp_tmp_pcb = *pcbs; 
  426.           tcp_tmp_pcb != NULL; 
  427.         tcp_tmp_pcb = tcp_tmp_pcb->next) { 
  428.                                 LWIP_ASSERT("TCP_REG: already registeredn", tcp_tmp_pcb != npcb); 
  429.                             } 
  430.                             LWIP_ASSERT("TCP_REG: pcb->state != CLOSED", npcb->state != CLOSED); 
  431.                             npcb->next = *pcbs; 
  432.                             LWIP_ASSERT("TCP_REG: npcb->next != npcb", npcb->next != npcb); 
  433.                             *(pcbs) = npcb; 
  434.                             LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); 
  435.               tcp_timer_needed(); 
  436.                             } while(0)
  437. #define TCP_RMV(pcbs, npcb) do { 
  438.                             LWIP_ASSERT("TCP_RMV: pcbs != NULL", *pcbs != NULL); 
  439.                             LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removing %p from %pn", npcb, *pcbs)); 
  440.                             if(*pcbs == npcb) { 
  441.                                *pcbs = (*pcbs)->next; 
  442.                             } else for(tcp_tmp_pcb = *pcbs; tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { 
  443.                                if(tcp_tmp_pcb->next != NULL && tcp_tmp_pcb->next == npcb) { 
  444.                                   tcp_tmp_pcb->next = npcb->next; 
  445.                                   break; 
  446.                                } 
  447.                             } 
  448.                             npcb->next = NULL; 
  449.                             LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); 
  450.                             LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %pn", npcb, *pcbs)); 
  451.                             } while(0)
  452. #else /* LWIP_DEBUG */
  453. #define TCP_REG(pcbs, npcb) do { 
  454.                             npcb->next = *pcbs; 
  455.                             *(pcbs) = npcb; 
  456.               tcp_timer_needed(); 
  457.                             } while(0)
  458. #define TCP_RMV(pcbs, npcb) do { 
  459.                             if(*(pcbs) == npcb) { 
  460.                                (*(pcbs)) = (*pcbs)->next; 
  461.                             } else for(tcp_tmp_pcb = *pcbs; tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { 
  462.                                if(tcp_tmp_pcb->next != NULL && tcp_tmp_pcb->next == npcb) { 
  463.                                   tcp_tmp_pcb->next = npcb->next; 
  464.                                   break; 
  465.                                } 
  466.                             } 
  467.                             npcb->next = NULL; 
  468.                             } while(0)
  469. #endif /* LWIP_DEBUG */
  470. #endif /* __LWIP_TCP_H__ */