/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
+ * derived from this software without specific prior written permission.
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
- *
+ *
* Author: Adam Dunkels <adam@sics.se>
*
*/
-#ifndef __LWIP_TCP_H__
-#define __LWIP_TCP_H__
+#ifndef LWIP_HDR_TCP_H
+#define LWIP_HDR_TCP_H
#include "lwip/opt.h"
*/
typedef err_t (*tcp_connected_fn)(void *arg, struct tcp_pcb *tpcb, err_t err);
+#if LWIP_WND_SCALE
+#define RCV_WND_SCALE(pcb, wnd) (((wnd) >> (pcb)->rcv_scale))
+#define SND_WND_SCALE(pcb, wnd) (((wnd) << (pcb)->snd_scale))
+#define TCPWND16(x) ((u16_t)LWIP_MIN((x), 0xFFFF))
+#define TCP_WND_MAX(pcb) ((tcpwnd_size_t)(((pcb)->flags & TF_WND_SCALE) ? TCP_WND : TCPWND16(TCP_WND)))
+typedef u32_t tcpwnd_size_t;
+typedef u16_t tcpflags_t;
+#else
+#define RCV_WND_SCALE(pcb, wnd) (wnd)
+#define SND_WND_SCALE(pcb, wnd) (wnd)
+#define TCPWND16(x) (x)
+#define TCP_WND_MAX(pcb) TCP_WND
+typedef u16_t tcpwnd_size_t;
+typedef u8_t tcpflags_t;
+#endif
+
enum tcp_state {
CLOSED = 0,
LISTEN = 1,
* @param pcb a new tcp_pcb that now is connected
* @param err an error argument (TODO: that is current always ERR_OK?)
* @return ERR_OK: accept the new connection,
- * any other err_t abortsthe new connection
+ * any other err_t aborts the new connection
*/
#define DEF_ACCEPT_CALLBACK tcp_accept_fn accept;
#else /* LWIP_CALLBACK_API */
/* ports are in host byte order */
u16_t remote_port;
-
- u8_t flags;
-#define TF_ACK_DELAY ((u8_t)0x01U) /* Delayed ACK. */
-#define TF_ACK_NOW ((u8_t)0x02U) /* Immediate ACK. */
-#define TF_INFR ((u8_t)0x04U) /* In fast recovery. */
-#define TF_TIMESTAMP ((u8_t)0x08U) /* Timestamp option enabled */
-#define TF_RXCLOSED ((u8_t)0x10U) /* rx closed by tcp_shutdown */
-#define TF_FIN ((u8_t)0x20U) /* Connection was closed locally (FIN segment enqueued). */
-#define TF_NODELAY ((u8_t)0x40U) /* Disable Nagle algorithm */
-#define TF_NAGLEMEMERR ((u8_t)0x80U) /* nagle enabled, memerr, try to output to prevent delayed ACK to happen */
+
+ tcpflags_t flags;
+#define TF_ACK_DELAY 0x01U /* Delayed ACK. */
+#define TF_ACK_NOW 0x02U /* Immediate ACK. */
+#define TF_INFR 0x04U /* In fast recovery. */
+#define TF_TIMESTAMP 0x08U /* Timestamp option enabled */
+#define TF_RXCLOSED 0x10U /* rx closed by tcp_shutdown */
+#define TF_FIN 0x20U /* Connection was closed locally (FIN segment enqueued). */
+#define TF_NODELAY 0x40U /* Disable Nagle algorithm */
+#define TF_NAGLEMEMERR 0x80U /* nagle enabled, memerr, try to output to prevent delayed ACK to happen */
+#if LWIP_WND_SCALE
+#define TF_WND_SCALE 0x0100U /* Window Scale option enabled */
+#endif
/* the rest of the fields are in host byte order
as we have to do some math with them */
/* Timers */
u8_t polltmr, pollinterval;
+ u8_t last_timer;
u32_t tmr;
/* receiver variables */
u32_t rcv_nxt; /* next seqno expected */
- u16_t rcv_wnd; /* receiver window available */
- u16_t rcv_ann_wnd; /* receiver window to announce */
+ tcpwnd_size_t rcv_wnd; /* receiver window available */
+ tcpwnd_size_t rcv_ann_wnd; /* receiver window to announce */
u32_t rcv_ann_right_edge; /* announced right edge of window */
/* Retransmission timer. */
u32_t lastack; /* Highest acknowledged seqno. */
/* congestion avoidance/control variables */
- u16_t cwnd;
- u16_t ssthresh;
+ tcpwnd_size_t cwnd;
+ tcpwnd_size_t ssthresh;
/* sender variables */
u32_t snd_nxt; /* next new seqno to be sent */
u32_t snd_wl1, snd_wl2; /* Sequence and acknowledgement numbers of last
window update. */
u32_t snd_lbb; /* Sequence number of next byte to be buffered. */
- u16_t snd_wnd; /* sender window */
+ tcpwnd_size_t snd_wnd; /* sender window */
+ tcpwnd_size_t snd_wnd_max; /* the maximum sender window announced by the remote host */
- u16_t acked;
+ tcpwnd_size_t acked;
- u16_t snd_buf; /* Available buffer space for sending (in bytes). */
+ tcpwnd_size_t snd_buf; /* Available buffer space for sending (in bytes). */
#define TCP_SNDQUEUELEN_OVERFLOW (0xffffU-3)
- u16_t snd_queuelen; /* Available buffer space for sending (in tcp_segs). */
+ u16_t snd_queuelen; /* Number of pbufs currently in the send buffer. */
#if TCP_OVERSIZE
/* Extra bytes available at the end of the last pbuf in unsent. */
u16_t unsent_oversize;
-#endif /* TCP_OVERSIZE */
+#endif /* TCP_OVERSIZE */
/* These are ordered by sequence number: */
struct tcp_seg *unsent; /* Unsent (queued) segments. */
struct tcp_seg *unacked; /* Sent but unacknowledged segments. */
-#if TCP_QUEUE_OOSEQ
+#if TCP_QUEUE_OOSEQ
struct tcp_seg *ooseq; /* Received out of sequence segments. */
#endif /* TCP_QUEUE_OOSEQ */
u32_t keep_intvl;
u32_t keep_cnt;
#endif /* LWIP_TCP_KEEPALIVE */
-
+
/* Persist timer counter */
- u32_t persist_cnt;
+ u8_t persist_cnt;
/* Persist timer back-off */
u8_t persist_backoff;
/* KEEPALIVE counter */
u8_t keep_cnt_sent;
+
+#if LWIP_WND_SCALE
+ u8_t snd_scale;
+ u8_t rcv_scale;
+#endif
};
struct tcp_pcb_listen {
u8_t backlog;
u8_t accepts_pending;
#endif /* TCP_LISTEN_BACKLOG */
-#if LWIP_IPV6
+#if LWIP_IPV4 && LWIP_IPV6
u8_t accept_any_ip_version;
-#endif /* LWIP_IPV6 */
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
};
#if LWIP_EVENT_API
void tcp_err (struct tcp_pcb *pcb, tcp_err_fn err);
#define tcp_mss(pcb) (((pcb)->flags & TF_TIMESTAMP) ? ((pcb)->mss - 12) : (pcb)->mss)
-#define tcp_sndbuf(pcb) ((pcb)->snd_buf)
+#define tcp_sndbuf(pcb) (TCPWND16((pcb)->snd_buf))
#define tcp_sndqueuelen(pcb) ((pcb)->snd_queuelen)
#define tcp_nagle_disable(pcb) ((pcb)->flags |= TF_NODELAY)
-#define tcp_nagle_enable(pcb) ((pcb)->flags &= ~TF_NODELAY)
+#define tcp_nagle_enable(pcb) ((pcb)->flags = (tcpflags_t)((pcb)->flags & ~TF_NODELAY))
#define tcp_nagle_disabled(pcb) (((pcb)->flags & TF_NODELAY) != 0)
#if TCP_LISTEN_BACKLOG
(((struct tcp_pcb_listen *)(pcb))->accepts_pending--); } while(0)
#else /* TCP_LISTEN_BACKLOG */
#define tcp_accepted(pcb) LWIP_ASSERT("pcb->state == LISTEN (called for wrong pcb?)", \
- pcb->state == LISTEN)
+ (pcb)->state == LISTEN)
#endif /* TCP_LISTEN_BACKLOG */
void tcp_recved (struct tcp_pcb *pcb, u16_t len);
-err_t tcp_bind (struct tcp_pcb *pcb, ip_addr_t *ipaddr,
+err_t tcp_bind (struct tcp_pcb *pcb, const ip_addr_t *ipaddr,
u16_t port);
-err_t tcp_connect (struct tcp_pcb *pcb, ip_addr_t *ipaddr,
+err_t tcp_connect (struct tcp_pcb *pcb, const ip_addr_t *ipaddr,
u16_t port, tcp_connected_fn connected);
struct tcp_pcb * tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog);
#if LWIP_IPV6
struct tcp_pcb * tcp_new_ip6 (void);
-#define tcp_bind_ip6(pcb, ip6addr, port) \
- tcp_bind(pcb, ip6_2_ip(ip6addr), port)
-#define tcp_connect_ip6(pcb, ip6addr, port, connected) \
- tcp_connect(pcb, ip6_2_ip(ip6addr), port, connected)
+#endif /* LWIP_IPV6 */
+#if LWIP_IPV4 && LWIP_IPV6
struct tcp_pcb * tcp_listen_dual_with_backlog(struct tcp_pcb *pcb, u8_t backlog);
#define tcp_listen_dual(pcb) tcp_listen_dual_with_backlog(pcb, TCP_DEFAULT_LISTEN_BACKLOG)
-#else /* LWIP_IPV6 */
+#else /* LWIP_IPV4 && LWIP_IPV6 */
#define tcp_listen_dual_with_backlog(pcb, backlog) tcp_listen_with_backlog(pcb, backlog)
#define tcp_listen_dual(pcb) tcp_listen(pcb)
-#endif /* LWIP_IPV6 */
+#endif /* LWIP_IPV4 && LWIP_IPV6 */
#ifdef __cplusplus
#endif /* LWIP_TCP */
-#endif /* __LWIP_TCP_H__ */
+#endif /* LWIP_HDR_TCP_H */