My fork of the HTTPServer (working)

Dependents:   DGWWebServer LAN2

Committer:
screamer
Date:
Mon Aug 06 09:23:14 2012 +0000
Revision:
0:7a64fbb4069d
[mbed] converted /DGWWebServer/HTTPServer

Who changed what in which revision?

UserRevisionLine numberNew contents of line
screamer 0:7a64fbb4069d 1 /*
screamer 0:7a64fbb4069d 2 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
screamer 0:7a64fbb4069d 3 * All rights reserved.
screamer 0:7a64fbb4069d 4 *
screamer 0:7a64fbb4069d 5 * Redistribution and use in source and binary forms, with or without modification,
screamer 0:7a64fbb4069d 6 * are permitted provided that the following conditions are met:
screamer 0:7a64fbb4069d 7 *
screamer 0:7a64fbb4069d 8 * 1. Redistributions of source code must retain the above copyright notice,
screamer 0:7a64fbb4069d 9 * this list of conditions and the following disclaimer.
screamer 0:7a64fbb4069d 10 * 2. Redistributions in binary form must reproduce the above copyright notice,
screamer 0:7a64fbb4069d 11 * this list of conditions and the following disclaimer in the documentation
screamer 0:7a64fbb4069d 12 * and/or other materials provided with the distribution.
screamer 0:7a64fbb4069d 13 * 3. The name of the author may not be used to endorse or promote products
screamer 0:7a64fbb4069d 14 * derived from this software without specific prior written permission.
screamer 0:7a64fbb4069d 15 *
screamer 0:7a64fbb4069d 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
screamer 0:7a64fbb4069d 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
screamer 0:7a64fbb4069d 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
screamer 0:7a64fbb4069d 19 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
screamer 0:7a64fbb4069d 20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
screamer 0:7a64fbb4069d 21 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
screamer 0:7a64fbb4069d 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
screamer 0:7a64fbb4069d 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
screamer 0:7a64fbb4069d 24 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
screamer 0:7a64fbb4069d 25 * OF SUCH DAMAGE.
screamer 0:7a64fbb4069d 26 *
screamer 0:7a64fbb4069d 27 * This file is part of the lwIP TCP/IP stack.
screamer 0:7a64fbb4069d 28 *
screamer 0:7a64fbb4069d 29 * Author: Adam Dunkels <adam@sics.se>
screamer 0:7a64fbb4069d 30 *
screamer 0:7a64fbb4069d 31 */
screamer 0:7a64fbb4069d 32 #ifndef __LWIP_TCP_H__
screamer 0:7a64fbb4069d 33 #define __LWIP_TCP_H__
screamer 0:7a64fbb4069d 34
screamer 0:7a64fbb4069d 35 #include "lwip/opt.h"
screamer 0:7a64fbb4069d 36
screamer 0:7a64fbb4069d 37 #if LWIP_TCP /* don't build if not configured for use in lwipopts.h */
screamer 0:7a64fbb4069d 38
screamer 0:7a64fbb4069d 39 #include "lwip/sys.h"
screamer 0:7a64fbb4069d 40 #include "lwip/mem.h"
screamer 0:7a64fbb4069d 41 #include "lwip/pbuf.h"
screamer 0:7a64fbb4069d 42 #include "lwip/ip.h"
screamer 0:7a64fbb4069d 43 #include "lwip/icmp.h"
screamer 0:7a64fbb4069d 44 #include "lwip/err.h"
screamer 0:7a64fbb4069d 45
screamer 0:7a64fbb4069d 46 #ifdef __cplusplus
screamer 0:7a64fbb4069d 47 extern "C" {
screamer 0:7a64fbb4069d 48 #endif
screamer 0:7a64fbb4069d 49
screamer 0:7a64fbb4069d 50 struct tcp_pcb;
screamer 0:7a64fbb4069d 51
screamer 0:7a64fbb4069d 52 /* Functions for interfacing with TCP: */
screamer 0:7a64fbb4069d 53
screamer 0:7a64fbb4069d 54 /* Lower layer interface to TCP: */
screamer 0:7a64fbb4069d 55 #define tcp_init() /* Compatibility define, not init needed. */
screamer 0:7a64fbb4069d 56 void tcp_tmr (void); /* Must be called every
screamer 0:7a64fbb4069d 57 TCP_TMR_INTERVAL
screamer 0:7a64fbb4069d 58 ms. (Typically 250 ms). */
screamer 0:7a64fbb4069d 59 /* Application program's interface: */
screamer 0:7a64fbb4069d 60 struct tcp_pcb * tcp_new (void);
screamer 0:7a64fbb4069d 61 struct tcp_pcb * tcp_alloc (u8_t prio);
screamer 0:7a64fbb4069d 62
screamer 0:7a64fbb4069d 63 void tcp_arg (struct tcp_pcb *pcb, void *arg);
screamer 0:7a64fbb4069d 64 void tcp_accept (struct tcp_pcb *pcb,
screamer 0:7a64fbb4069d 65 err_t (* accept)(void *arg, struct tcp_pcb *newpcb,
screamer 0:7a64fbb4069d 66 err_t err));
screamer 0:7a64fbb4069d 67 void tcp_recv (struct tcp_pcb *pcb,
screamer 0:7a64fbb4069d 68 err_t (* recv)(void *arg, struct tcp_pcb *tpcb,
screamer 0:7a64fbb4069d 69 struct pbuf *p, err_t err));
screamer 0:7a64fbb4069d 70 void tcp_sent (struct tcp_pcb *pcb,
screamer 0:7a64fbb4069d 71 err_t (* sent)(void *arg, struct tcp_pcb *tpcb,
screamer 0:7a64fbb4069d 72 u16_t len));
screamer 0:7a64fbb4069d 73 void tcp_poll (struct tcp_pcb *pcb,
screamer 0:7a64fbb4069d 74 err_t (* poll)(void *arg, struct tcp_pcb *tpcb),
screamer 0:7a64fbb4069d 75 u8_t interval);
screamer 0:7a64fbb4069d 76 void tcp_err (struct tcp_pcb *pcb,
screamer 0:7a64fbb4069d 77 void (* err)(void *arg, err_t err));
screamer 0:7a64fbb4069d 78
screamer 0:7a64fbb4069d 79 #define tcp_mss(pcb) ((pcb)->mss)
screamer 0:7a64fbb4069d 80 #define tcp_sndbuf(pcb) ((pcb)->snd_buf)
screamer 0:7a64fbb4069d 81
screamer 0:7a64fbb4069d 82 #if TCP_LISTEN_BACKLOG
screamer 0:7a64fbb4069d 83 #define tcp_accepted(pcb) (((struct tcp_pcb_listen *)(pcb))->accepts_pending--)
screamer 0:7a64fbb4069d 84 #else /* TCP_LISTEN_BACKLOG */
screamer 0:7a64fbb4069d 85 #define tcp_accepted(pcb)
screamer 0:7a64fbb4069d 86 #endif /* TCP_LISTEN_BACKLOG */
screamer 0:7a64fbb4069d 87
screamer 0:7a64fbb4069d 88 void tcp_recved (struct tcp_pcb *pcb, u16_t len);
screamer 0:7a64fbb4069d 89 err_t tcp_bind (struct tcp_pcb *pcb, struct ip_addr *ipaddr,
screamer 0:7a64fbb4069d 90 u16_t port);
screamer 0:7a64fbb4069d 91 err_t tcp_connect (struct tcp_pcb *pcb, struct ip_addr *ipaddr,
screamer 0:7a64fbb4069d 92 u16_t port, err_t (* connected)(void *arg,
screamer 0:7a64fbb4069d 93 struct tcp_pcb *tpcb,
screamer 0:7a64fbb4069d 94 err_t err));
screamer 0:7a64fbb4069d 95
screamer 0:7a64fbb4069d 96 struct tcp_pcb * tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog);
screamer 0:7a64fbb4069d 97 #define tcp_listen(pcb) tcp_listen_with_backlog(pcb, TCP_DEFAULT_LISTEN_BACKLOG)
screamer 0:7a64fbb4069d 98
screamer 0:7a64fbb4069d 99 void tcp_abandon (struct tcp_pcb *pcb, int reset);
screamer 0:7a64fbb4069d 100 #define tcp_abort(pcb) tcp_abandon((pcb), 1)
screamer 0:7a64fbb4069d 101 err_t tcp_close (struct tcp_pcb *pcb);
screamer 0:7a64fbb4069d 102
screamer 0:7a64fbb4069d 103 /* Flags for "apiflags" parameter in tcp_write and tcp_enqueue */
screamer 0:7a64fbb4069d 104 #define TCP_WRITE_FLAG_COPY 0x01
screamer 0:7a64fbb4069d 105 #define TCP_WRITE_FLAG_MORE 0x02
screamer 0:7a64fbb4069d 106
screamer 0:7a64fbb4069d 107 err_t tcp_write (struct tcp_pcb *pcb, const void *dataptr, u16_t len,
screamer 0:7a64fbb4069d 108 u8_t apiflags);
screamer 0:7a64fbb4069d 109
screamer 0:7a64fbb4069d 110 void tcp_setprio (struct tcp_pcb *pcb, u8_t prio);
screamer 0:7a64fbb4069d 111
screamer 0:7a64fbb4069d 112 #define TCP_PRIO_MIN 1
screamer 0:7a64fbb4069d 113 #define TCP_PRIO_NORMAL 64
screamer 0:7a64fbb4069d 114 #define TCP_PRIO_MAX 127
screamer 0:7a64fbb4069d 115
screamer 0:7a64fbb4069d 116 /* It is also possible to call these two functions at the right
screamer 0:7a64fbb4069d 117 intervals (instead of calling tcp_tmr()). */
screamer 0:7a64fbb4069d 118 void tcp_slowtmr (void);
screamer 0:7a64fbb4069d 119 void tcp_fasttmr (void);
screamer 0:7a64fbb4069d 120
screamer 0:7a64fbb4069d 121
screamer 0:7a64fbb4069d 122 /* Only used by IP to pass a TCP segment to TCP: */
screamer 0:7a64fbb4069d 123 void tcp_input (struct pbuf *p, struct netif *inp);
screamer 0:7a64fbb4069d 124 /* Used within the TCP code only: */
screamer 0:7a64fbb4069d 125 err_t tcp_output (struct tcp_pcb *pcb);
screamer 0:7a64fbb4069d 126 void tcp_rexmit (struct tcp_pcb *pcb);
screamer 0:7a64fbb4069d 127 void tcp_rexmit_rto (struct tcp_pcb *pcb);
screamer 0:7a64fbb4069d 128 u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb);
screamer 0:7a64fbb4069d 129
screamer 0:7a64fbb4069d 130 /**
screamer 0:7a64fbb4069d 131 * This is the Nagle algorithm: inhibit the sending of new TCP
screamer 0:7a64fbb4069d 132 * segments when new outgoing data arrives from the user if any
screamer 0:7a64fbb4069d 133 * previously transmitted data on the connection remains
screamer 0:7a64fbb4069d 134 * unacknowledged.
screamer 0:7a64fbb4069d 135 */
screamer 0:7a64fbb4069d 136 #define tcp_do_output_nagle(tpcb) ((((tpcb)->unacked == NULL) || \
screamer 0:7a64fbb4069d 137 ((tpcb)->flags & TF_NODELAY) || \
screamer 0:7a64fbb4069d 138 (((tpcb)->unsent != NULL) && ((tpcb)->unsent->next != NULL))) ? \
screamer 0:7a64fbb4069d 139 1 : 0)
screamer 0:7a64fbb4069d 140 #define tcp_output_nagle(tpcb) (tcp_do_output_nagle(tpcb) ? tcp_output(tpcb) : ERR_OK)
screamer 0:7a64fbb4069d 141
screamer 0:7a64fbb4069d 142
screamer 0:7a64fbb4069d 143 #define TCP_SEQ_LT(a,b) ((s32_t)((a)-(b)) < 0)
screamer 0:7a64fbb4069d 144 #define TCP_SEQ_LEQ(a,b) ((s32_t)((a)-(b)) <= 0)
screamer 0:7a64fbb4069d 145 #define TCP_SEQ_GT(a,b) ((s32_t)((a)-(b)) > 0)
screamer 0:7a64fbb4069d 146 #define TCP_SEQ_GEQ(a,b) ((s32_t)((a)-(b)) >= 0)
screamer 0:7a64fbb4069d 147 /* is b<=a<=c? */
screamer 0:7a64fbb4069d 148 #if 0 /* see bug #10548 */
screamer 0:7a64fbb4069d 149 #define TCP_SEQ_BETWEEN(a,b,c) ((c)-(b) >= (a)-(b))
screamer 0:7a64fbb4069d 150 #endif
screamer 0:7a64fbb4069d 151 #define TCP_SEQ_BETWEEN(a,b,c) (TCP_SEQ_GEQ(a,b) && TCP_SEQ_LEQ(a,c))
screamer 0:7a64fbb4069d 152 #define TCP_FIN 0x01U
screamer 0:7a64fbb4069d 153 #define TCP_SYN 0x02U
screamer 0:7a64fbb4069d 154 #define TCP_RST 0x04U
screamer 0:7a64fbb4069d 155 #define TCP_PSH 0x08U
screamer 0:7a64fbb4069d 156 #define TCP_ACK 0x10U
screamer 0:7a64fbb4069d 157 #define TCP_URG 0x20U
screamer 0:7a64fbb4069d 158 #define TCP_ECE 0x40U
screamer 0:7a64fbb4069d 159 #define TCP_CWR 0x80U
screamer 0:7a64fbb4069d 160
screamer 0:7a64fbb4069d 161 #define TCP_FLAGS 0x3fU
screamer 0:7a64fbb4069d 162
screamer 0:7a64fbb4069d 163 /* Length of the TCP header, excluding options. */
screamer 0:7a64fbb4069d 164 #define TCP_HLEN 20
screamer 0:7a64fbb4069d 165
screamer 0:7a64fbb4069d 166 #ifndef TCP_TMR_INTERVAL
screamer 0:7a64fbb4069d 167 #define TCP_TMR_INTERVAL 250 /* The TCP timer interval in milliseconds. */
screamer 0:7a64fbb4069d 168 #endif /* TCP_TMR_INTERVAL */
screamer 0:7a64fbb4069d 169
screamer 0:7a64fbb4069d 170 #ifndef TCP_FAST_INTERVAL
screamer 0:7a64fbb4069d 171 #define TCP_FAST_INTERVAL TCP_TMR_INTERVAL /* the fine grained timeout in milliseconds */
screamer 0:7a64fbb4069d 172 #endif /* TCP_FAST_INTERVAL */
screamer 0:7a64fbb4069d 173
screamer 0:7a64fbb4069d 174 #ifndef TCP_SLOW_INTERVAL
screamer 0:7a64fbb4069d 175 #define TCP_SLOW_INTERVAL (2*TCP_TMR_INTERVAL) /* the coarse grained timeout in milliseconds */
screamer 0:7a64fbb4069d 176 #endif /* TCP_SLOW_INTERVAL */
screamer 0:7a64fbb4069d 177
screamer 0:7a64fbb4069d 178 #define TCP_FIN_WAIT_TIMEOUT 20000 /* milliseconds */
screamer 0:7a64fbb4069d 179 #define TCP_SYN_RCVD_TIMEOUT 20000 /* milliseconds */
screamer 0:7a64fbb4069d 180
screamer 0:7a64fbb4069d 181 #define TCP_OOSEQ_TIMEOUT 6U /* x RTO */
screamer 0:7a64fbb4069d 182
screamer 0:7a64fbb4069d 183 #ifndef TCP_MSL
screamer 0:7a64fbb4069d 184 #define TCP_MSL 60000UL /* The maximum segment lifetime in milliseconds */
screamer 0:7a64fbb4069d 185 #endif
screamer 0:7a64fbb4069d 186
screamer 0:7a64fbb4069d 187 /* Keepalive values, compliant with RFC 1122. Don't change this unless you know what you're doing */
screamer 0:7a64fbb4069d 188 #ifndef TCP_KEEPIDLE_DEFAULT
screamer 0:7a64fbb4069d 189 #define TCP_KEEPIDLE_DEFAULT 7200000UL /* Default KEEPALIVE timer in milliseconds */
screamer 0:7a64fbb4069d 190 #endif
screamer 0:7a64fbb4069d 191
screamer 0:7a64fbb4069d 192 #ifndef TCP_KEEPINTVL_DEFAULT
screamer 0:7a64fbb4069d 193 #define TCP_KEEPINTVL_DEFAULT 75000UL /* Default Time between KEEPALIVE probes in milliseconds */
screamer 0:7a64fbb4069d 194 #endif
screamer 0:7a64fbb4069d 195
screamer 0:7a64fbb4069d 196 #ifndef TCP_KEEPCNT_DEFAULT
screamer 0:7a64fbb4069d 197 #define TCP_KEEPCNT_DEFAULT 9U /* Default Counter for KEEPALIVE probes */
screamer 0:7a64fbb4069d 198 #endif
screamer 0:7a64fbb4069d 199
screamer 0:7a64fbb4069d 200 #define TCP_MAXIDLE TCP_KEEPCNT_DEFAULT * TCP_KEEPINTVL_DEFAULT /* Maximum KEEPALIVE probe time */
screamer 0:7a64fbb4069d 201
screamer 0:7a64fbb4069d 202 /* Fields are (of course) in network byte order.
screamer 0:7a64fbb4069d 203 * Some fields are converted to host byte order in tcp_input().
screamer 0:7a64fbb4069d 204 */
screamer 0:7a64fbb4069d 205 #ifdef PACK_STRUCT_USE_INCLUDES
screamer 0:7a64fbb4069d 206 # include "arch/bpstruct.h"
screamer 0:7a64fbb4069d 207 #endif
screamer 0:7a64fbb4069d 208 PACK_STRUCT_BEGIN
screamer 0:7a64fbb4069d 209 struct tcp_hdr {
screamer 0:7a64fbb4069d 210 PACK_STRUCT_FIELD(u16_t src);
screamer 0:7a64fbb4069d 211 PACK_STRUCT_FIELD(u16_t dest);
screamer 0:7a64fbb4069d 212 PACK_STRUCT_FIELD(u32_t seqno);
screamer 0:7a64fbb4069d 213 PACK_STRUCT_FIELD(u32_t ackno);
screamer 0:7a64fbb4069d 214 PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags);
screamer 0:7a64fbb4069d 215 PACK_STRUCT_FIELD(u16_t wnd);
screamer 0:7a64fbb4069d 216 PACK_STRUCT_FIELD(u16_t chksum);
screamer 0:7a64fbb4069d 217 PACK_STRUCT_FIELD(u16_t urgp);
screamer 0:7a64fbb4069d 218 } PACK_STRUCT_STRUCT;
screamer 0:7a64fbb4069d 219 PACK_STRUCT_END
screamer 0:7a64fbb4069d 220 #ifdef PACK_STRUCT_USE_INCLUDES
screamer 0:7a64fbb4069d 221 # include "arch/epstruct.h"
screamer 0:7a64fbb4069d 222 #endif
screamer 0:7a64fbb4069d 223
screamer 0:7a64fbb4069d 224 #define TCPH_OFFSET(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 8)
screamer 0:7a64fbb4069d 225 #define TCPH_HDRLEN(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 12)
screamer 0:7a64fbb4069d 226 #define TCPH_FLAGS(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS)
screamer 0:7a64fbb4069d 227
screamer 0:7a64fbb4069d 228 #define TCPH_OFFSET_SET(phdr, offset) (phdr)->_hdrlen_rsvd_flags = htons(((offset) << 8) | TCPH_FLAGS(phdr))
screamer 0:7a64fbb4069d 229 #define TCPH_HDRLEN_SET(phdr, len) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | TCPH_FLAGS(phdr))
screamer 0:7a64fbb4069d 230 #define TCPH_FLAGS_SET(phdr, flags) (phdr)->_hdrlen_rsvd_flags = htons((ntohs((phdr)->_hdrlen_rsvd_flags) & ~TCP_FLAGS) | (flags))
screamer 0:7a64fbb4069d 231 #define TCPH_SET_FLAG(phdr, flags ) (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (flags))
screamer 0:7a64fbb4069d 232 #define TCPH_UNSET_FLAG(phdr, flags) (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (TCPH_FLAGS(phdr) & ~(flags)) )
screamer 0:7a64fbb4069d 233
screamer 0:7a64fbb4069d 234 #define TCP_TCPLEN(seg) ((seg)->len + ((TCPH_FLAGS((seg)->tcphdr) & TCP_FIN || \
screamer 0:7a64fbb4069d 235 TCPH_FLAGS((seg)->tcphdr) & TCP_SYN)? 1: 0))
screamer 0:7a64fbb4069d 236
screamer 0:7a64fbb4069d 237 enum tcp_state {
screamer 0:7a64fbb4069d 238 CLOSED = 0,
screamer 0:7a64fbb4069d 239 LISTEN = 1,
screamer 0:7a64fbb4069d 240 SYN_SENT = 2,
screamer 0:7a64fbb4069d 241 SYN_RCVD = 3,
screamer 0:7a64fbb4069d 242 ESTABLISHED = 4,
screamer 0:7a64fbb4069d 243 FIN_WAIT_1 = 5,
screamer 0:7a64fbb4069d 244 FIN_WAIT_2 = 6,
screamer 0:7a64fbb4069d 245 CLOSE_WAIT = 7,
screamer 0:7a64fbb4069d 246 CLOSING = 8,
screamer 0:7a64fbb4069d 247 LAST_ACK = 9,
screamer 0:7a64fbb4069d 248 TIME_WAIT = 10
screamer 0:7a64fbb4069d 249 };
screamer 0:7a64fbb4069d 250
screamer 0:7a64fbb4069d 251 /** Flags used on input processing, not on pcb->flags
screamer 0:7a64fbb4069d 252 */
screamer 0:7a64fbb4069d 253 #define TF_RESET (u8_t)0x08U /* Connection was reset. */
screamer 0:7a64fbb4069d 254 #define TF_CLOSED (u8_t)0x10U /* Connection was sucessfully closed. */
screamer 0:7a64fbb4069d 255 #define TF_GOT_FIN (u8_t)0x20U /* Connection was closed by the remote end. */
screamer 0:7a64fbb4069d 256
screamer 0:7a64fbb4069d 257
screamer 0:7a64fbb4069d 258 #if LWIP_CALLBACK_API
screamer 0:7a64fbb4069d 259 /* Function to call when a listener has been connected.
screamer 0:7a64fbb4069d 260 * @param arg user-supplied argument (tcp_pcb.callback_arg)
screamer 0:7a64fbb4069d 261 * @param pcb a new tcp_pcb that now is connected
screamer 0:7a64fbb4069d 262 * @param err an error argument (TODO: that is current always ERR_OK?)
screamer 0:7a64fbb4069d 263 * @return ERR_OK: accept the new connection,
screamer 0:7a64fbb4069d 264 * any other err_t abortsthe new connection
screamer 0:7a64fbb4069d 265 */
screamer 0:7a64fbb4069d 266 #define DEF_ACCEPT_CALLBACK err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err)
screamer 0:7a64fbb4069d 267 #else /* LWIP_CALLBACK_API */
screamer 0:7a64fbb4069d 268 #define DEF_ACCEPT_CALLBACK
screamer 0:7a64fbb4069d 269 #endif /* LWIP_CALLBACK_API */
screamer 0:7a64fbb4069d 270
screamer 0:7a64fbb4069d 271 /**
screamer 0:7a64fbb4069d 272 * members common to struct tcp_pcb and struct tcp_listen_pcb
screamer 0:7a64fbb4069d 273 */
screamer 0:7a64fbb4069d 274 #define TCP_PCB_COMMON(type) \
screamer 0:7a64fbb4069d 275 type *next; /* for the linked list */ \
screamer 0:7a64fbb4069d 276 enum tcp_state state; /* TCP state */ \
screamer 0:7a64fbb4069d 277 u8_t prio; \
screamer 0:7a64fbb4069d 278 void *callback_arg; \
screamer 0:7a64fbb4069d 279 /* ports are in host byte order */ \
screamer 0:7a64fbb4069d 280 u16_t local_port; \
screamer 0:7a64fbb4069d 281 /* the accept callback for listen- and normal pcbs, if LWIP_CALLBACK_API */ \
screamer 0:7a64fbb4069d 282 DEF_ACCEPT_CALLBACK
screamer 0:7a64fbb4069d 283
screamer 0:7a64fbb4069d 284
screamer 0:7a64fbb4069d 285 /* the TCP protocol control block */
screamer 0:7a64fbb4069d 286 struct tcp_pcb {
screamer 0:7a64fbb4069d 287 /** common PCB members */
screamer 0:7a64fbb4069d 288 IP_PCB;
screamer 0:7a64fbb4069d 289 /** protocol specific PCB members */
screamer 0:7a64fbb4069d 290 TCP_PCB_COMMON(struct tcp_pcb);
screamer 0:7a64fbb4069d 291
screamer 0:7a64fbb4069d 292 /* ports are in host byte order */
screamer 0:7a64fbb4069d 293 u16_t remote_port;
screamer 0:7a64fbb4069d 294
screamer 0:7a64fbb4069d 295 u8_t flags;
screamer 0:7a64fbb4069d 296 #define TF_ACK_DELAY ((u8_t)0x01U) /* Delayed ACK. */
screamer 0:7a64fbb4069d 297 #define TF_ACK_NOW ((u8_t)0x02U) /* Immediate ACK. */
screamer 0:7a64fbb4069d 298 #define TF_INFR ((u8_t)0x04U) /* In fast recovery. */
screamer 0:7a64fbb4069d 299 #define TF_TIMESTAMP ((u8_t)0x08U) /* Timestamp option enabled */
screamer 0:7a64fbb4069d 300 #define TF_FIN ((u8_t)0x20U) /* Connection was closed locally (FIN segment enqueued). */
screamer 0:7a64fbb4069d 301 #define TF_NODELAY ((u8_t)0x40U) /* Disable Nagle algorithm */
screamer 0:7a64fbb4069d 302 #define TF_NAGLEMEMERR ((u8_t)0x80U) /* nagle enabled, memerr, try to output to prevent delayed ACK to happen */
screamer 0:7a64fbb4069d 303
screamer 0:7a64fbb4069d 304 /* the rest of the fields are in host byte order
screamer 0:7a64fbb4069d 305 as we have to do some math with them */
screamer 0:7a64fbb4069d 306 /* receiver variables */
screamer 0:7a64fbb4069d 307 u32_t rcv_nxt; /* next seqno expected */
screamer 0:7a64fbb4069d 308 u16_t rcv_wnd; /* receiver window available */
screamer 0:7a64fbb4069d 309 u16_t rcv_ann_wnd; /* receiver window to announce */
screamer 0:7a64fbb4069d 310 u32_t rcv_ann_right_edge; /* announced right edge of window */
screamer 0:7a64fbb4069d 311
screamer 0:7a64fbb4069d 312 /* Timers */
screamer 0:7a64fbb4069d 313 u32_t tmr;
screamer 0:7a64fbb4069d 314 u8_t polltmr, pollinterval;
screamer 0:7a64fbb4069d 315
screamer 0:7a64fbb4069d 316 /* Retransmission timer. */
screamer 0:7a64fbb4069d 317 s16_t rtime;
screamer 0:7a64fbb4069d 318
screamer 0:7a64fbb4069d 319 u16_t mss; /* maximum segment size */
screamer 0:7a64fbb4069d 320
screamer 0:7a64fbb4069d 321 /* RTT (round trip time) estimation variables */
screamer 0:7a64fbb4069d 322 u32_t rttest; /* RTT estimate in 500ms ticks */
screamer 0:7a64fbb4069d 323 u32_t rtseq; /* sequence number being timed */
screamer 0:7a64fbb4069d 324 s16_t sa, sv; /* @todo document this */
screamer 0:7a64fbb4069d 325
screamer 0:7a64fbb4069d 326 s16_t rto; /* retransmission time-out */
screamer 0:7a64fbb4069d 327 u8_t nrtx; /* number of retransmissions */
screamer 0:7a64fbb4069d 328
screamer 0:7a64fbb4069d 329 /* fast retransmit/recovery */
screamer 0:7a64fbb4069d 330 u32_t lastack; /* Highest acknowledged seqno. */
screamer 0:7a64fbb4069d 331 u8_t dupacks;
screamer 0:7a64fbb4069d 332
screamer 0:7a64fbb4069d 333 /* congestion avoidance/control variables */
screamer 0:7a64fbb4069d 334 u16_t cwnd;
screamer 0:7a64fbb4069d 335 u16_t ssthresh;
screamer 0:7a64fbb4069d 336
screamer 0:7a64fbb4069d 337 /* sender variables */
screamer 0:7a64fbb4069d 338 u32_t snd_nxt, /* next seqno to be sent */
screamer 0:7a64fbb4069d 339 snd_max; /* Highest seqno sent. */
screamer 0:7a64fbb4069d 340 u16_t snd_wnd; /* sender window */
screamer 0:7a64fbb4069d 341 u32_t snd_wl1, snd_wl2, /* Sequence and acknowledgement numbers of last
screamer 0:7a64fbb4069d 342 window update. */
screamer 0:7a64fbb4069d 343 snd_lbb; /* Sequence number of next byte to be buffered. */
screamer 0:7a64fbb4069d 344
screamer 0:7a64fbb4069d 345 u16_t acked;
screamer 0:7a64fbb4069d 346
screamer 0:7a64fbb4069d 347 u16_t snd_buf; /* Available buffer space for sending (in bytes). */
screamer 0:7a64fbb4069d 348 #define TCP_SNDQUEUELEN_OVERFLOW (0xffff-3)
screamer 0:7a64fbb4069d 349 u16_t snd_queuelen; /* Available buffer space for sending (in tcp_segs). */
screamer 0:7a64fbb4069d 350
screamer 0:7a64fbb4069d 351
screamer 0:7a64fbb4069d 352 /* These are ordered by sequence number: */
screamer 0:7a64fbb4069d 353 struct tcp_seg *unsent; /* Unsent (queued) segments. */
screamer 0:7a64fbb4069d 354 struct tcp_seg *unacked; /* Sent but unacknowledged segments. */
screamer 0:7a64fbb4069d 355 #if TCP_QUEUE_OOSEQ
screamer 0:7a64fbb4069d 356 struct tcp_seg *ooseq; /* Received out of sequence segments. */
screamer 0:7a64fbb4069d 357 #endif /* TCP_QUEUE_OOSEQ */
screamer 0:7a64fbb4069d 358
screamer 0:7a64fbb4069d 359 struct pbuf *refused_data; /* Data previously received but not yet taken by upper layer */
screamer 0:7a64fbb4069d 360
screamer 0:7a64fbb4069d 361 #if LWIP_CALLBACK_API
screamer 0:7a64fbb4069d 362 /* Function to be called when more send buffer space is available.
screamer 0:7a64fbb4069d 363 * @param arg user-supplied argument (tcp_pcb.callback_arg)
screamer 0:7a64fbb4069d 364 * @param pcb the tcp_pcb which has send buffer space available
screamer 0:7a64fbb4069d 365 * @param space the amount of bytes available
screamer 0:7a64fbb4069d 366 * @return ERR_OK: try to send some data by calling tcp_output
screamer 0:7a64fbb4069d 367 */
screamer 0:7a64fbb4069d 368 err_t (* sent)(void *arg, struct tcp_pcb *pcb, u16_t space);
screamer 0:7a64fbb4069d 369
screamer 0:7a64fbb4069d 370 /* Function to be called when (in-sequence) data has arrived.
screamer 0:7a64fbb4069d 371 * @param arg user-supplied argument (tcp_pcb.callback_arg)
screamer 0:7a64fbb4069d 372 * @param pcb the tcp_pcb for which data has arrived
screamer 0:7a64fbb4069d 373 * @param p the packet buffer which arrived
screamer 0:7a64fbb4069d 374 * @param err an error argument (TODO: that is current always ERR_OK?)
screamer 0:7a64fbb4069d 375 * @return ERR_OK: try to send some data by calling tcp_output
screamer 0:7a64fbb4069d 376 */
screamer 0:7a64fbb4069d 377 err_t (* recv)(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);
screamer 0:7a64fbb4069d 378
screamer 0:7a64fbb4069d 379 /* Function to be called when a connection has been set up.
screamer 0:7a64fbb4069d 380 * @param arg user-supplied argument (tcp_pcb.callback_arg)
screamer 0:7a64fbb4069d 381 * @param pcb the tcp_pcb that now is connected
screamer 0:7a64fbb4069d 382 * @param err an error argument (TODO: that is current always ERR_OK?)
screamer 0:7a64fbb4069d 383 * @return value is currently ignored
screamer 0:7a64fbb4069d 384 */
screamer 0:7a64fbb4069d 385 err_t (* connected)(void *arg, struct tcp_pcb *pcb, err_t err);
screamer 0:7a64fbb4069d 386
screamer 0:7a64fbb4069d 387 /* Function which is called periodically.
screamer 0:7a64fbb4069d 388 * The period can be adjusted in multiples of the TCP slow timer interval
screamer 0:7a64fbb4069d 389 * by changing tcp_pcb.polltmr.
screamer 0:7a64fbb4069d 390 * @param arg user-supplied argument (tcp_pcb.callback_arg)
screamer 0:7a64fbb4069d 391 * @param pcb the tcp_pcb to poll for
screamer 0:7a64fbb4069d 392 * @return ERR_OK: try to send some data by calling tcp_output
screamer 0:7a64fbb4069d 393 */
screamer 0:7a64fbb4069d 394 err_t (* poll)(void *arg, struct tcp_pcb *pcb);
screamer 0:7a64fbb4069d 395
screamer 0:7a64fbb4069d 396 /* Function to be called whenever a fatal error occurs.
screamer 0:7a64fbb4069d 397 * There is no pcb parameter since most of the times, the pcb is
screamer 0:7a64fbb4069d 398 * already deallocated (or there is no pcb) when this function is called.
screamer 0:7a64fbb4069d 399 * @param arg user-supplied argument (tcp_pcb.callback_arg)
screamer 0:7a64fbb4069d 400 * @param err an indication why the error callback is called:
screamer 0:7a64fbb4069d 401 * ERR_ABRT: aborted through tcp_abort or by a TCP timer
screamer 0:7a64fbb4069d 402 * ERR_RST: the connection was reset by the remote host
screamer 0:7a64fbb4069d 403 */
screamer 0:7a64fbb4069d 404 void (* errf)(void *arg, err_t err);
screamer 0:7a64fbb4069d 405 #endif /* LWIP_CALLBACK_API */
screamer 0:7a64fbb4069d 406
screamer 0:7a64fbb4069d 407 #if LWIP_TCP_TIMESTAMPS
screamer 0:7a64fbb4069d 408 u32_t ts_lastacksent;
screamer 0:7a64fbb4069d 409 u32_t ts_recent;
screamer 0:7a64fbb4069d 410 #endif /* LWIP_TCP_TIMESTAMPS */
screamer 0:7a64fbb4069d 411
screamer 0:7a64fbb4069d 412 /* idle time before KEEPALIVE is sent */
screamer 0:7a64fbb4069d 413 u32_t keep_idle;
screamer 0:7a64fbb4069d 414 #if LWIP_TCP_KEEPALIVE
screamer 0:7a64fbb4069d 415 u32_t keep_intvl;
screamer 0:7a64fbb4069d 416 u32_t keep_cnt;
screamer 0:7a64fbb4069d 417 #endif /* LWIP_TCP_KEEPALIVE */
screamer 0:7a64fbb4069d 418
screamer 0:7a64fbb4069d 419 /* Persist timer counter */
screamer 0:7a64fbb4069d 420 u32_t persist_cnt;
screamer 0:7a64fbb4069d 421 /* Persist timer back-off */
screamer 0:7a64fbb4069d 422 u8_t persist_backoff;
screamer 0:7a64fbb4069d 423
screamer 0:7a64fbb4069d 424 /* KEEPALIVE counter */
screamer 0:7a64fbb4069d 425 u8_t keep_cnt_sent;
screamer 0:7a64fbb4069d 426 };
screamer 0:7a64fbb4069d 427
screamer 0:7a64fbb4069d 428 struct tcp_pcb_listen {
screamer 0:7a64fbb4069d 429 /* Common members of all PCB types */
screamer 0:7a64fbb4069d 430 IP_PCB;
screamer 0:7a64fbb4069d 431 /* Protocol specific PCB members */
screamer 0:7a64fbb4069d 432 TCP_PCB_COMMON(struct tcp_pcb_listen);
screamer 0:7a64fbb4069d 433
screamer 0:7a64fbb4069d 434 #if TCP_LISTEN_BACKLOG
screamer 0:7a64fbb4069d 435 u8_t backlog;
screamer 0:7a64fbb4069d 436 u8_t accepts_pending;
screamer 0:7a64fbb4069d 437 #endif /* TCP_LISTEN_BACKLOG */
screamer 0:7a64fbb4069d 438 };
screamer 0:7a64fbb4069d 439
screamer 0:7a64fbb4069d 440 #if LWIP_EVENT_API
screamer 0:7a64fbb4069d 441
screamer 0:7a64fbb4069d 442 enum lwip_event {
screamer 0:7a64fbb4069d 443 LWIP_EVENT_ACCEPT,
screamer 0:7a64fbb4069d 444 LWIP_EVENT_SENT,
screamer 0:7a64fbb4069d 445 LWIP_EVENT_RECV,
screamer 0:7a64fbb4069d 446 LWIP_EVENT_CONNECTED,
screamer 0:7a64fbb4069d 447 LWIP_EVENT_POLL,
screamer 0:7a64fbb4069d 448 LWIP_EVENT_ERR
screamer 0:7a64fbb4069d 449 };
screamer 0:7a64fbb4069d 450
screamer 0:7a64fbb4069d 451 err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb,
screamer 0:7a64fbb4069d 452 enum lwip_event,
screamer 0:7a64fbb4069d 453 struct pbuf *p,
screamer 0:7a64fbb4069d 454 u16_t size,
screamer 0:7a64fbb4069d 455 err_t err);
screamer 0:7a64fbb4069d 456
screamer 0:7a64fbb4069d 457 #define TCP_EVENT_ACCEPT(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
screamer 0:7a64fbb4069d 458 LWIP_EVENT_ACCEPT, NULL, 0, err)
screamer 0:7a64fbb4069d 459 #define TCP_EVENT_SENT(pcb,space,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
screamer 0:7a64fbb4069d 460 LWIP_EVENT_SENT, NULL, space, ERR_OK)
screamer 0:7a64fbb4069d 461 #define TCP_EVENT_RECV(pcb,p,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
screamer 0:7a64fbb4069d 462 LWIP_EVENT_RECV, (p), 0, (err))
screamer 0:7a64fbb4069d 463 #define TCP_EVENT_CONNECTED(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
screamer 0:7a64fbb4069d 464 LWIP_EVENT_CONNECTED, NULL, 0, (err))
screamer 0:7a64fbb4069d 465 #define TCP_EVENT_POLL(pcb,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
screamer 0:7a64fbb4069d 466 LWIP_EVENT_POLL, NULL, 0, ERR_OK)
screamer 0:7a64fbb4069d 467 #define TCP_EVENT_ERR(errf,arg,err) lwip_tcp_event((arg), NULL, \
screamer 0:7a64fbb4069d 468 LWIP_EVENT_ERR, NULL, 0, (err))
screamer 0:7a64fbb4069d 469 #else /* LWIP_EVENT_API */
screamer 0:7a64fbb4069d 470
screamer 0:7a64fbb4069d 471 #define TCP_EVENT_ACCEPT(pcb,err,ret) \
screamer 0:7a64fbb4069d 472 do { \
screamer 0:7a64fbb4069d 473 if((pcb)->accept != NULL) \
screamer 0:7a64fbb4069d 474 (ret) = (pcb)->accept((pcb)->callback_arg,(pcb),(err)); \
screamer 0:7a64fbb4069d 475 } while (0)
screamer 0:7a64fbb4069d 476
screamer 0:7a64fbb4069d 477 #define TCP_EVENT_SENT(pcb,space,ret) \
screamer 0:7a64fbb4069d 478 do { \
screamer 0:7a64fbb4069d 479 if((pcb)->sent != NULL) \
screamer 0:7a64fbb4069d 480 (ret) = (pcb)->sent((pcb)->callback_arg,(pcb),(space)); \
screamer 0:7a64fbb4069d 481 } while (0)
screamer 0:7a64fbb4069d 482
screamer 0:7a64fbb4069d 483 #define TCP_EVENT_RECV(pcb,p,err,ret) \
screamer 0:7a64fbb4069d 484 do { \
screamer 0:7a64fbb4069d 485 if((pcb)->recv != NULL) { \
screamer 0:7a64fbb4069d 486 (ret) = (pcb)->recv((pcb)->callback_arg,(pcb),(p),(err)); \
screamer 0:7a64fbb4069d 487 } else { \
screamer 0:7a64fbb4069d 488 (ret) = ERR_OK; \
screamer 0:7a64fbb4069d 489 if (p != NULL) \
screamer 0:7a64fbb4069d 490 pbuf_free(p); \
screamer 0:7a64fbb4069d 491 } \
screamer 0:7a64fbb4069d 492 } while (0)
screamer 0:7a64fbb4069d 493
screamer 0:7a64fbb4069d 494 #define TCP_EVENT_CONNECTED(pcb,err,ret) \
screamer 0:7a64fbb4069d 495 do { \
screamer 0:7a64fbb4069d 496 if((pcb)->connected != NULL) \
screamer 0:7a64fbb4069d 497 (ret) = (pcb)->connected((pcb)->callback_arg,(pcb),(err)); \
screamer 0:7a64fbb4069d 498 } while (0)
screamer 0:7a64fbb4069d 499
screamer 0:7a64fbb4069d 500 #define TCP_EVENT_POLL(pcb,ret) \
screamer 0:7a64fbb4069d 501 do { \
screamer 0:7a64fbb4069d 502 if((pcb)->poll != NULL) \
screamer 0:7a64fbb4069d 503 (ret) = (pcb)->poll((pcb)->callback_arg,(pcb)); \
screamer 0:7a64fbb4069d 504 } while (0)
screamer 0:7a64fbb4069d 505
screamer 0:7a64fbb4069d 506 #define TCP_EVENT_ERR(errf,arg,err) \
screamer 0:7a64fbb4069d 507 do { \
screamer 0:7a64fbb4069d 508 if((errf) != NULL) \
screamer 0:7a64fbb4069d 509 (errf)((arg),(err)); \
screamer 0:7a64fbb4069d 510 } while (0)
screamer 0:7a64fbb4069d 511
screamer 0:7a64fbb4069d 512 #endif /* LWIP_EVENT_API */
screamer 0:7a64fbb4069d 513
screamer 0:7a64fbb4069d 514 /* This structure represents a TCP segment on the unsent and unacked queues */
screamer 0:7a64fbb4069d 515 struct tcp_seg {
screamer 0:7a64fbb4069d 516 struct tcp_seg *next; /* used when putting segements on a queue */
screamer 0:7a64fbb4069d 517 struct pbuf *p; /* buffer containing data + TCP header */
screamer 0:7a64fbb4069d 518 void *dataptr; /* pointer to the TCP data in the pbuf */
screamer 0:7a64fbb4069d 519 u16_t len; /* the TCP length of this segment */
screamer 0:7a64fbb4069d 520 u8_t flags;
screamer 0:7a64fbb4069d 521 #define TF_SEG_OPTS_MSS (u8_t)0x01U /* Include MSS option. */
screamer 0:7a64fbb4069d 522 #define TF_SEG_OPTS_TS (u8_t)0x02U /* Include timestamp option. */
screamer 0:7a64fbb4069d 523 struct tcp_hdr *tcphdr; /* the TCP header */
screamer 0:7a64fbb4069d 524 };
screamer 0:7a64fbb4069d 525
screamer 0:7a64fbb4069d 526 #define LWIP_TCP_OPT_LENGTH(flags) \
screamer 0:7a64fbb4069d 527 (flags & TF_SEG_OPTS_MSS ? 4 : 0) + \
screamer 0:7a64fbb4069d 528 (flags & TF_SEG_OPTS_TS ? 12 : 0)
screamer 0:7a64fbb4069d 529
screamer 0:7a64fbb4069d 530 /** This returns a TCP header option for MSS in an u32_t */
screamer 0:7a64fbb4069d 531 #define TCP_BUILD_MSS_OPTION(x) (x) = htonl(((u32_t)2 << 24) | \
screamer 0:7a64fbb4069d 532 ((u32_t)4 << 16) | \
screamer 0:7a64fbb4069d 533 (((u32_t)TCP_MSS / 256) << 8) | \
screamer 0:7a64fbb4069d 534 (TCP_MSS & 255))
screamer 0:7a64fbb4069d 535
screamer 0:7a64fbb4069d 536 /* Internal functions and global variables: */
screamer 0:7a64fbb4069d 537 struct tcp_pcb *tcp_pcb_copy(struct tcp_pcb *pcb);
screamer 0:7a64fbb4069d 538 void tcp_pcb_purge(struct tcp_pcb *pcb);
screamer 0:7a64fbb4069d 539 void tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb);
screamer 0:7a64fbb4069d 540
screamer 0:7a64fbb4069d 541 u8_t tcp_segs_free(struct tcp_seg *seg);
screamer 0:7a64fbb4069d 542 u8_t tcp_seg_free(struct tcp_seg *seg);
screamer 0:7a64fbb4069d 543 struct tcp_seg *tcp_seg_copy(struct tcp_seg *seg);
screamer 0:7a64fbb4069d 544
screamer 0:7a64fbb4069d 545 #define tcp_ack(pcb) \
screamer 0:7a64fbb4069d 546 do { \
screamer 0:7a64fbb4069d 547 if((pcb)->flags & TF_ACK_DELAY) { \
screamer 0:7a64fbb4069d 548 (pcb)->flags &= ~TF_ACK_DELAY; \
screamer 0:7a64fbb4069d 549 (pcb)->flags |= TF_ACK_NOW; \
screamer 0:7a64fbb4069d 550 tcp_output(pcb); \
screamer 0:7a64fbb4069d 551 } \
screamer 0:7a64fbb4069d 552 else { \
screamer 0:7a64fbb4069d 553 (pcb)->flags |= TF_ACK_DELAY; \
screamer 0:7a64fbb4069d 554 } \
screamer 0:7a64fbb4069d 555 } while (0)
screamer 0:7a64fbb4069d 556
screamer 0:7a64fbb4069d 557 #define tcp_ack_now(pcb) \
screamer 0:7a64fbb4069d 558 do { \
screamer 0:7a64fbb4069d 559 (pcb)->flags |= TF_ACK_NOW; \
screamer 0:7a64fbb4069d 560 tcp_output(pcb); \
screamer 0:7a64fbb4069d 561 } while (0)
screamer 0:7a64fbb4069d 562
screamer 0:7a64fbb4069d 563 err_t tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags);
screamer 0:7a64fbb4069d 564 err_t tcp_enqueue(struct tcp_pcb *pcb, void *dataptr, u16_t len,
screamer 0:7a64fbb4069d 565 u8_t flags, u8_t apiflags, u8_t optflags);
screamer 0:7a64fbb4069d 566
screamer 0:7a64fbb4069d 567 void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg);
screamer 0:7a64fbb4069d 568
screamer 0:7a64fbb4069d 569 void tcp_rst(u32_t seqno, u32_t ackno,
screamer 0:7a64fbb4069d 570 struct ip_addr *local_ip, struct ip_addr *remote_ip,
screamer 0:7a64fbb4069d 571 u16_t local_port, u16_t remote_port);
screamer 0:7a64fbb4069d 572
screamer 0:7a64fbb4069d 573 u32_t tcp_next_iss(void);
screamer 0:7a64fbb4069d 574
screamer 0:7a64fbb4069d 575 void tcp_keepalive(struct tcp_pcb *pcb);
screamer 0:7a64fbb4069d 576 void tcp_zero_window_probe(struct tcp_pcb *pcb);
screamer 0:7a64fbb4069d 577
screamer 0:7a64fbb4069d 578 #if TCP_CALCULATE_EFF_SEND_MSS
screamer 0:7a64fbb4069d 579 u16_t tcp_eff_send_mss(u16_t sendmss, struct ip_addr *addr);
screamer 0:7a64fbb4069d 580 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
screamer 0:7a64fbb4069d 581
screamer 0:7a64fbb4069d 582 extern struct tcp_pcb *tcp_input_pcb;
screamer 0:7a64fbb4069d 583 extern u32_t tcp_ticks;
screamer 0:7a64fbb4069d 584
screamer 0:7a64fbb4069d 585 #if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG
screamer 0:7a64fbb4069d 586 void tcp_debug_print(struct tcp_hdr *tcphdr);
screamer 0:7a64fbb4069d 587 void tcp_debug_print_flags(u8_t flags);
screamer 0:7a64fbb4069d 588 void tcp_debug_print_state(enum tcp_state s);
screamer 0:7a64fbb4069d 589 void tcp_debug_print_pcbs(void);
screamer 0:7a64fbb4069d 590 s16_t tcp_pcbs_sane(void);
screamer 0:7a64fbb4069d 591 #else
screamer 0:7a64fbb4069d 592 # define tcp_debug_print(tcphdr)
screamer 0:7a64fbb4069d 593 # define tcp_debug_print_flags(flags)
screamer 0:7a64fbb4069d 594 # define tcp_debug_print_state(s)
screamer 0:7a64fbb4069d 595 # define tcp_debug_print_pcbs()
screamer 0:7a64fbb4069d 596 # define tcp_pcbs_sane() 1
screamer 0:7a64fbb4069d 597 #endif /* TCP_DEBUG */
screamer 0:7a64fbb4069d 598
screamer 0:7a64fbb4069d 599 #if NO_SYS
screamer 0:7a64fbb4069d 600 #define tcp_timer_needed()
screamer 0:7a64fbb4069d 601 #else
screamer 0:7a64fbb4069d 602 void tcp_timer_needed(void);
screamer 0:7a64fbb4069d 603 #endif
screamer 0:7a64fbb4069d 604
screamer 0:7a64fbb4069d 605 /* The TCP PCB lists. */
screamer 0:7a64fbb4069d 606 union tcp_listen_pcbs_t { /* List of all TCP PCBs in LISTEN state. */
screamer 0:7a64fbb4069d 607 struct tcp_pcb_listen *listen_pcbs;
screamer 0:7a64fbb4069d 608 struct tcp_pcb *pcbs;
screamer 0:7a64fbb4069d 609 };
screamer 0:7a64fbb4069d 610 extern union tcp_listen_pcbs_t tcp_listen_pcbs;
screamer 0:7a64fbb4069d 611 extern struct tcp_pcb *tcp_active_pcbs; /* List of all TCP PCBs that are in a
screamer 0:7a64fbb4069d 612 state in which they accept or send
screamer 0:7a64fbb4069d 613 data. */
screamer 0:7a64fbb4069d 614 extern struct tcp_pcb *tcp_tw_pcbs; /* List of all TCP PCBs in TIME-WAIT. */
screamer 0:7a64fbb4069d 615
screamer 0:7a64fbb4069d 616 extern struct tcp_pcb *tcp_tmp_pcb; /* Only used for temporary storage. */
screamer 0:7a64fbb4069d 617
screamer 0:7a64fbb4069d 618 /* Axioms about the above lists:
screamer 0:7a64fbb4069d 619 1) Every TCP PCB that is not CLOSED is in one of the lists.
screamer 0:7a64fbb4069d 620 2) A PCB is only in one of the lists.
screamer 0:7a64fbb4069d 621 3) All PCBs in the tcp_listen_pcbs list is in LISTEN state.
screamer 0:7a64fbb4069d 622 4) All PCBs in the tcp_tw_pcbs list is in TIME-WAIT state.
screamer 0:7a64fbb4069d 623 */
screamer 0:7a64fbb4069d 624
screamer 0:7a64fbb4069d 625 /* Define two macros, TCP_REG and TCP_RMV that registers a TCP PCB
screamer 0:7a64fbb4069d 626 with a PCB list or removes a PCB from a list, respectively. */
screamer 0:7a64fbb4069d 627 #if 0
screamer 0:7a64fbb4069d 628 #define TCP_REG(pcbs, npcb) do {\
screamer 0:7a64fbb4069d 629 LWIP_DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %d\n", npcb, npcb->local_port)); \
screamer 0:7a64fbb4069d 630 for(tcp_tmp_pcb = *pcbs; \
screamer 0:7a64fbb4069d 631 tcp_tmp_pcb != NULL; \
screamer 0:7a64fbb4069d 632 tcp_tmp_pcb = tcp_tmp_pcb->next) { \
screamer 0:7a64fbb4069d 633 LWIP_ASSERT("TCP_REG: already registered\n", tcp_tmp_pcb != npcb); \
screamer 0:7a64fbb4069d 634 } \
screamer 0:7a64fbb4069d 635 LWIP_ASSERT("TCP_REG: pcb->state != CLOSED", npcb->state != CLOSED); \
screamer 0:7a64fbb4069d 636 npcb->next = *pcbs; \
screamer 0:7a64fbb4069d 637 LWIP_ASSERT("TCP_REG: npcb->next != npcb", npcb->next != npcb); \
screamer 0:7a64fbb4069d 638 *(pcbs) = npcb; \
screamer 0:7a64fbb4069d 639 LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \
screamer 0:7a64fbb4069d 640 tcp_timer_needed(); \
screamer 0:7a64fbb4069d 641 } while(0)
screamer 0:7a64fbb4069d 642 #define TCP_RMV(pcbs, npcb) do { \
screamer 0:7a64fbb4069d 643 LWIP_ASSERT("TCP_RMV: pcbs != NULL", *pcbs != NULL); \
screamer 0:7a64fbb4069d 644 LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removing %p from %p\n", npcb, *pcbs)); \
screamer 0:7a64fbb4069d 645 if(*pcbs == npcb) { \
screamer 0:7a64fbb4069d 646 *pcbs = (*pcbs)->next; \
screamer 0:7a64fbb4069d 647 } else for(tcp_tmp_pcb = *pcbs; tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \
screamer 0:7a64fbb4069d 648 if(tcp_tmp_pcb->next != NULL && tcp_tmp_pcb->next == npcb) { \
screamer 0:7a64fbb4069d 649 tcp_tmp_pcb->next = npcb->next; \
screamer 0:7a64fbb4069d 650 break; \
screamer 0:7a64fbb4069d 651 } \
screamer 0:7a64fbb4069d 652 } \
screamer 0:7a64fbb4069d 653 npcb->next = NULL; \
screamer 0:7a64fbb4069d 654 LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \
screamer 0:7a64fbb4069d 655 LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", npcb, *pcbs)); \
screamer 0:7a64fbb4069d 656 } while(0)
screamer 0:7a64fbb4069d 657
screamer 0:7a64fbb4069d 658 #else /* LWIP_DEBUG */
screamer 0:7a64fbb4069d 659
screamer 0:7a64fbb4069d 660 #define TCP_REG(pcbs, npcb) \
screamer 0:7a64fbb4069d 661 do { \
screamer 0:7a64fbb4069d 662 npcb->next = *pcbs; \
screamer 0:7a64fbb4069d 663 *(pcbs) = npcb; \
screamer 0:7a64fbb4069d 664 tcp_timer_needed(); \
screamer 0:7a64fbb4069d 665 } while (0)
screamer 0:7a64fbb4069d 666
screamer 0:7a64fbb4069d 667 #define TCP_RMV(pcbs, npcb) \
screamer 0:7a64fbb4069d 668 do { \
screamer 0:7a64fbb4069d 669 if(*(pcbs) == npcb) { \
screamer 0:7a64fbb4069d 670 (*(pcbs)) = (*pcbs)->next; \
screamer 0:7a64fbb4069d 671 } \
screamer 0:7a64fbb4069d 672 else { \
screamer 0:7a64fbb4069d 673 for(tcp_tmp_pcb = *pcbs; \
screamer 0:7a64fbb4069d 674 tcp_tmp_pcb != NULL; \
screamer 0:7a64fbb4069d 675 tcp_tmp_pcb = tcp_tmp_pcb->next) { \
screamer 0:7a64fbb4069d 676 if(tcp_tmp_pcb->next != NULL && tcp_tmp_pcb->next == npcb) { \
screamer 0:7a64fbb4069d 677 tcp_tmp_pcb->next = npcb->next; \
screamer 0:7a64fbb4069d 678 break; \
screamer 0:7a64fbb4069d 679 } \
screamer 0:7a64fbb4069d 680 } \
screamer 0:7a64fbb4069d 681 } \
screamer 0:7a64fbb4069d 682 npcb->next = NULL; \
screamer 0:7a64fbb4069d 683 } while(0)
screamer 0:7a64fbb4069d 684
screamer 0:7a64fbb4069d 685 #endif /* LWIP_DEBUG */
screamer 0:7a64fbb4069d 686
screamer 0:7a64fbb4069d 687 #ifdef __cplusplus
screamer 0:7a64fbb4069d 688 }
screamer 0:7a64fbb4069d 689 #endif
screamer 0:7a64fbb4069d 690
screamer 0:7a64fbb4069d 691 #endif /* LWIP_TCP */
screamer 0:7a64fbb4069d 692
screamer 0:7a64fbb4069d 693 #endif /* __LWIP_TCP_H__ */