mirror of
https://git.savannah.nongnu.org/git/lwip.git
synced 2026-05-25 01:27:05 +08:00
Partial SACK (RFC 2018) support
Adds partial support for selective acknowledgements (RFC 2018). This change makes lwIP negotiate SACK support, and include SACK data in outgoing empty ACK packets. It does not include it in outgoing packets with data payload. It also does not add support for handling incoming SACKs. Signed-off-by: goldsimon <goldsimon@gmx.de>
This commit is contained in:
committed by
goldsimon
parent
d262132b92
commit
b1a3c37c3c
@@ -1211,6 +1211,27 @@
|
||||
#define TCP_QUEUE_OOSEQ (LWIP_TCP)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* LWIP_TCP_SACK_OUT==1: TCP will support sending selective acknowledgements (SACKs).
|
||||
*/
|
||||
#if !defined LWIP_TCP_SACK_OUT || defined __DOXYGEN__
|
||||
#define LWIP_TCP_SACK_OUT 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* LWIP_TCP_MAX_SACK_NUM: The maximum number of SACK values to include in TCP packets.
|
||||
* Must be at least 1, but is only used if LWIP_TCP_SACK_OUT is enabled.
|
||||
* NOTE: Even though we never send more than 4 SACK ranges in a single packet
|
||||
* (depending on other options), setting this option to values greater than 4 is not pointless.
|
||||
* This is basically the max number of SACK ranges we want to keep track of.
|
||||
* As new data is delivered, some of the SACK ranges may be removed or merged.
|
||||
* In that case some of those older SACK ranges may be used again.
|
||||
* The amount of memory used to store SACK ranges is LWIP_TCP_MAX_SACK_NUM * 8 bytes for each TCP PCB.
|
||||
*/
|
||||
#if !defined LWIP_TCP_MAX_SACK_NUM || defined __DOXYGEN__
|
||||
#define LWIP_TCP_MAX_SACK_NUM 4
|
||||
#endif
|
||||
|
||||
/**
|
||||
* TCP_MSS: TCP Maximum segment size. (default is 536, a conservative default,
|
||||
* you might want to increase this.)
|
||||
|
||||
@@ -264,6 +264,7 @@ struct tcp_seg {
|
||||
#define TF_SEG_DATA_CHECKSUMMED (u8_t)0x04U /* ALL data (not the header) is
|
||||
checksummed into 'chksum' */
|
||||
#define TF_SEG_OPTS_WND_SCALE (u8_t)0x08U /* Include WND SCALE option */
|
||||
#define TF_SEG_OPTS_SACK_PERM (u8_t)0x10U /* Include SACK Permitted option */
|
||||
struct tcp_hdr *tcphdr; /* the TCP header */
|
||||
};
|
||||
|
||||
@@ -271,6 +272,7 @@ struct tcp_seg {
|
||||
#define LWIP_TCP_OPT_NOP 1
|
||||
#define LWIP_TCP_OPT_MSS 2
|
||||
#define LWIP_TCP_OPT_WS 3
|
||||
#define LWIP_TCP_OPT_SACK_PERM 4
|
||||
#define LWIP_TCP_OPT_TS 8
|
||||
|
||||
#define LWIP_TCP_OPT_LEN_MSS 4
|
||||
@@ -287,10 +289,18 @@ struct tcp_seg {
|
||||
#define LWIP_TCP_OPT_LEN_WS_OUT 0
|
||||
#endif
|
||||
|
||||
#if LWIP_TCP_SACK_OUT
|
||||
#define LWIP_TCP_OPT_LEN_SACK_PERM 2
|
||||
#define LWIP_TCP_OPT_LEN_SACK_PERM_OUT 4 /* aligned for output (includes NOP padding) */
|
||||
#else
|
||||
#define LWIP_TCP_OPT_LEN_SACK_PERM_OUT 0
|
||||
#endif
|
||||
|
||||
#define LWIP_TCP_OPT_LENGTH(flags) \
|
||||
(flags & TF_SEG_OPTS_MSS ? LWIP_TCP_OPT_LEN_MSS : 0) + \
|
||||
(flags & TF_SEG_OPTS_TS ? LWIP_TCP_OPT_LEN_TS_OUT : 0) + \
|
||||
(flags & TF_SEG_OPTS_WND_SCALE ? LWIP_TCP_OPT_LEN_WS_OUT : 0)
|
||||
(flags & TF_SEG_OPTS_MSS ? LWIP_TCP_OPT_LEN_MSS : 0) + \
|
||||
(flags & TF_SEG_OPTS_TS ? LWIP_TCP_OPT_LEN_TS_OUT : 0) + \
|
||||
(flags & TF_SEG_OPTS_WND_SCALE ? LWIP_TCP_OPT_LEN_WS_OUT : 0) + \
|
||||
(flags & TF_SEG_OPTS_SACK_PERM ? LWIP_TCP_OPT_LEN_SACK_PERM_OUT : 0)
|
||||
|
||||
/** This returns a TCP header option for MSS in an u32_t */
|
||||
#define TCP_BUILD_MSS_OPTION(mss) lwip_htonl(0x02040000 | ((mss) & 0xFFFF))
|
||||
|
||||
@@ -214,6 +214,9 @@ struct tcp_pcb {
|
||||
#define TF_TIMESTAMP 0x0400U /* Timestamp option enabled */
|
||||
#endif
|
||||
#define TF_RTO 0x0800U /* RTO timer has fired, in-flight data moved to unsent and being retransmitted */
|
||||
#if LWIP_TCP_SACK_OUT
|
||||
#define TF_SACK 0x1000U /* Selective ACKs enabled */
|
||||
#endif
|
||||
|
||||
/* the rest of the fields are in host byte order
|
||||
as we have to do some math with them */
|
||||
@@ -229,6 +232,19 @@ struct tcp_pcb {
|
||||
tcpwnd_size_t rcv_ann_wnd; /* receiver window to announce */
|
||||
u32_t rcv_ann_right_edge; /* announced right edge of window */
|
||||
|
||||
#ifdef LWIP_TCP_SACK_OUT
|
||||
/* SACK ranges to include in ACK packets.
|
||||
SACK entry is invalid if left=right. */
|
||||
struct
|
||||
{
|
||||
/* Left edge of the SACK: the first acknowledged sequence number. */
|
||||
u32_t left;
|
||||
|
||||
/* Right edge of the SACK: the last acknowledged sequence number +1 (so first NOT acknowledged). */
|
||||
u32_t right;
|
||||
} rcv_sacks[LWIP_TCP_MAX_SACK_NUM];
|
||||
#endif
|
||||
|
||||
/* Retransmission timer. */
|
||||
s16_t rtime;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user