From b45511118421920771f5dcd5e4bafc04376e4450 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Sat, 16 Jan 2010 20:16:33 +0100 Subject: [PATCH] Make MSS clamping configurable, but enabled by default. It can either be set globally in tinc.conf, or per-node in host config files. --- doc/tinc.conf.5.in | 5 +++++ doc/tinc.texi | 6 ++++++ src/connection.h | 1 + src/net_setup.c | 6 ++++++ src/protocol_auth.c | 13 +++++++++++++ src/route.c | 5 ++++- 6 files changed, 35 insertions(+), 1 deletion(-) diff --git a/doc/tinc.conf.5.in b/doc/tinc.conf.5.in index 8e644450..e2ded368 100644 --- a/doc/tinc.conf.5.in +++ b/doc/tinc.conf.5.in @@ -347,6 +347,11 @@ Furthermore, specifying will turn off packet encryption. It is best to use only those ciphers which support CBC mode. +.It Va ClampMSS Li = yes | no Pq yes +This option specifies whether tinc should clamp the maximum segment size (MSS) +of TCP packets to the path MTU. This helps in situations where ICMP +Fragmentation Needed or Packet too Big messages are dropped by firewalls. + .It Va Compression Li = Ar level Pq 0 This option sets the level of compression used for UDP packets. Possible values are 0 (off), 1 (fast zlib) and any integer up to 9 (best zlib), diff --git a/doc/tinc.texi b/doc/tinc.texi index 35658188..d2b09fa1 100644 --- a/doc/tinc.texi +++ b/doc/tinc.texi @@ -956,6 +956,12 @@ Any cipher supported by OpenSSL is recognized. Furthermore, specifying "none" will turn off packet encryption. It is best to use only those ciphers which support CBC mode. +@cindex ClampMSS +@item ClampMSS = (yes) +This option specifies whether tinc should clamp the maximum segment size (MSS) +of TCP packets to the path MTU. This helps in situations where ICMP +Fragmentation Needed or Packet too Big messages are dropped by firewalls. + @cindex Compression @item Compression = <@var{level}> (0) This option sets the level of compression used for UDP packets. diff --git a/src/connection.h b/src/connection.h index b3a7e33f..d5c14bd5 100644 --- a/src/connection.h +++ b/src/connection.h @@ -29,6 +29,7 @@ #define OPTION_INDIRECT 0x0001 #define OPTION_TCPONLY 0x0002 #define OPTION_PMTU_DISCOVERY 0x0004 +#define OPTION_CLAMP_MSS 0x0008 typedef struct connection_status_t { int pinged:1; /* sent ping */ diff --git a/src/net_setup.c b/src/net_setup.c index 369c8a40..7d20803d 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -303,6 +303,12 @@ bool setup_myself(void) { if(choice) myself->options |= OPTION_PMTU_DISCOVERY; + choice = true; + get_config_bool(lookup_config(config_tree, "ClampMSS"), &choice); + get_config_bool(lookup_config(myself->connection->config_tree, "ClampMSS"), &choice); + if(choice) + myself->options |= OPTION_CLAMP_MSS; + get_config_bool(lookup_config(config_tree, "PriorityInheritance"), &priorityinheritance); #if !defined(SOL_IP) || !defined(IP_TOS) diff --git a/src/protocol_auth.c b/src/protocol_auth.c index c2df4cd8..4707dceb 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -453,6 +453,11 @@ bool send_ack(connection_t *c) { if(myself->options & OPTION_PMTU_DISCOVERY) c->options |= OPTION_PMTU_DISCOVERY; + choice = myself->options & OPTION_CLAMP_MSS; + get_config_bool(lookup_config(c->config_tree, "ClampMSS"), &choice); + if(choice) + c->options |= OPTION_CLAMP_MSS; + get_config_int(lookup_config(c->config_tree, "Weight"), &c->estimated_weight); return send_request(c, "%d %s %d %x", ACK, myport, c->estimated_weight, c->options); @@ -496,6 +501,7 @@ bool ack_h(connection_t *c) { int weight, mtu; uint32_t options; node_t *n; + bool choice; if(sscanf(c->buffer, "%*d " MAX_STRING " %d %x", hisport, &weight, &options) != 3) { logger(LOG_ERR, "Got bad %s from %s (%s)", "ACK", c->name, @@ -536,6 +542,13 @@ bool ack_h(connection_t *c) { if(get_config_int(lookup_config(myself->connection->config_tree, "PMTU"), &mtu) && mtu < n->mtu) n->mtu = mtu; + if(get_config_bool(lookup_config(c->config_tree, "ClampMSS"), &choice)) { + if(choice) + c->options |= OPTION_CLAMP_MSS; + else + c->options &= ~OPTION_CLAMP_MSS; + } + /* Activate this connection */ c->allow_request = ALL; diff --git a/src/route.c b/src/route.c index 77bec047..c04b0ad7 100644 --- a/src/route.c +++ b/src/route.c @@ -94,7 +94,7 @@ static bool checklength(node_t *source, vpn_packet_t *packet, length_t length) { } static void clamp_mss(const node_t *source, const node_t *via, vpn_packet_t *packet) { - if(!via || via == myself) + if(!via || via == myself || !(via->options & OPTION_CLAMP_MSS)) return; /* Find TCP header */ @@ -112,6 +112,9 @@ static void clamp_mss(const node_t *source, const node_t *via, vpn_packet_t *pac /* Use data offset field to calculate length of options field */ int len = ((packet->data[start + 12] >> 4) - 5) * 4; + if(packet->len < start + 20 + len) + return; + /* Search for MSS option header */ for(int i = 0; i < len;) { if(packet->data[start + 20 + i] == 0) -- 2.20.1