From 95425552d7c6551236281871176a50c5c5dfb601 Mon Sep 17 00:00:00 2001 From: goldsimon Date: Wed, 21 Nov 2007 18:37:23 +0000 Subject: [PATCH] Implemented calculating the effective send-mss based on the MTU of the netif used to send. Enabled by default. Disable by setting LWIP_CALCULATE_EFF_SEND_MSS to 0. This fixes bug #21535. --- CHANGELOG | 5 +++++ src/core/tcp.c | 27 +++++++++++++++++++++++++++ src/core/tcp_in.c | 6 ++++++ src/include/lwip/opt.h | 16 ++++++++++++++++ src/include/lwip/tcp.h | 4 ++++ 5 files changed, 58 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 8c5377a1..b8e5a51b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -19,6 +19,11 @@ HISTORY ++ New features: + 2007-11-21 Simon Goldschmidt + * tcp.h, opt.h, tcp.c, tcp_in.c: implemented calculating the effective send-mss + based on the MTU of the netif used to send. Enabled by default. Disable by + setting LWIP_CALCULATE_EFF_SEND_MSS to 0. This fixes bug #21535. + 2007-11-19 Frédéric Bernon * api_msg.c, dns.h, dns.c: Implement DNS_DOES_NAME_CHECK option (check if name received match the name query), implement DNS_USES_STATIC_BUF (the place where diff --git a/src/core/tcp.c b/src/core/tcp.c index 422f0eb3..34e460f2 100644 --- a/src/core/tcp.c +++ b/src/core/tcp.c @@ -493,6 +493,9 @@ tcp_connect(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port, pcb->snd_wnd = TCP_WND; /* The send MSS is updated when an MSS option is received. */ pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS; +#if LWIP_CALCULATE_EFF_SEND_MSS + pcb->mss = tcp_eff_send_mss(pcb->mss, ipaddr); +#endif /* LWIP_CALCULATE_EFF_SEND_MSS */ pcb->cwnd = 1; pcb->ssthresh = pcb->mss * 10; pcb->state = SYN_SENT; @@ -1151,6 +1154,30 @@ tcp_next_iss(void) return iss; } +#if LWIP_CALCULATE_EFF_SEND_MSS +/** + * Calcluates the effective send mss that can be used for a specific IP address + * by using ip_route to determin the netif used to send to the address and + * calculating the minimum of TCP_MSS and that netif's mtu (if set). + */ +u16_t +tcp_eff_send_mss(u16_t sendmss, struct ip_addr *addr) +{ + u16_t mss_s; + struct netif *outif; + + outif = ip_route(addr); + if ((outif != NULL) && (outif->mtu != 0)) { + mss_s = outif->mtu - IP_HLEN - TCP_HLEN; + /* RFC 1122, chap 4.2.2.6: + * Eff.snd.MSS = min(SendMSS+20, MMS_S) - TCPhdrsize - IPoptionsize + * but we only send options with SYN and that is never filled with data! */ + sendmss = LWIP_MIN(sendmss, mss_s); + } + return sendmss; +} +#endif /* LWIP_CALCULATE_EFF_SEND_MSS */ + #if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG /** * Print a tcp header for debugging purposes. diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c index 7dbe1f93..fac1f8cf 100644 --- a/src/core/tcp_in.c +++ b/src/core/tcp_in.c @@ -412,6 +412,9 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) /* Parse any options in the SYN. */ tcp_parseopt(npcb); +#if LWIP_CALCULATE_EFF_SEND_MSS + npcb->mss = tcp_eff_send_mss(npcb->mss, &(npcb->remote_ip)); +#endif /* LWIP_CALCULATE_EFF_SEND_MSS */ snmp_inc_tcppassiveopens(); @@ -519,6 +522,9 @@ tcp_process(struct tcp_pcb *pcb) /* Parse any options in the SYNACK before using pcb->mss since that * can be changed by the received options! */ tcp_parseopt(pcb); +#if LWIP_CALCULATE_EFF_SEND_MSS + pcb->mss = tcp_eff_send_mss(pcb->mss, &(pcb->remote_ip)); +#endif /* LWIP_CALCULATE_EFF_SEND_MSS */ /* Set ssthresh again after changing pcb->mss (already set in tcp_connect * but for the default value of pcb->mss) */ diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index 2c9579ad..c79aec9f 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -636,11 +636,27 @@ /** * TCP_MSS: TCP Maximum segment size. (default is 128, a *very* * conservative default.) + * For the receive side, this MSS is advertised to the remote side + * when opening a connection. For the transmit size, this MSS sets + * an upper limit on the MSS advertised by the remote host. */ #ifndef TCP_MSS #define TCP_MSS 128 #endif +/** + * LWIP_CALCULATE_EFF_SEND_MSS: "The maximum size of a segment that TCP really + * sends, the 'effective send MSS,' MUST be the smaller of the send MSS (which + * reflects the available reassembly buffer size at the remote host) and the + * largest size permitted by the IP layer" (RFC 1122) + * Setting this to 1 enables code that checks TCP_MSS against the MTU of the + * netif used for a connection and limits the MSS it would be too big otherwise. + */ +#ifndef LWIP_CALCULATE_EFF_SEND_MSS +#define LWIP_CALCULATE_EFF_SEND_MSS 1 +#endif + + /** * TCP_SND_BUF: TCP sender buffer space (bytes). */ diff --git a/src/include/lwip/tcp.h b/src/include/lwip/tcp.h index ecf5f778..6130d196 100644 --- a/src/include/lwip/tcp.h +++ b/src/include/lwip/tcp.h @@ -508,6 +508,10 @@ u32_t tcp_next_iss(void); void tcp_keepalive(struct tcp_pcb *pcb); +#if LWIP_CALCULATE_EFF_SEND_MSS +u16_t tcp_eff_send_mss(u16_t sendmss, struct ip_addr *addr); +#endif /* LWIP_CALCULATE_EFF_SEND_MSS*/ + extern struct tcp_pcb *tcp_input_pcb; extern u32_t tcp_ticks;