Make MSS clamping configurable, but enabled by default.
authorGuus Sliepen <guus@tinc-vpn.org>
Sat, 16 Jan 2010 19:16:33 +0000 (20:16 +0100)
committerGuus Sliepen <guus@tinc-vpn.org>
Sat, 16 Jan 2010 19:16:33 +0000 (20:16 +0100)
It can either be set globally in tinc.conf, or per-node in host config files.

doc/tinc.conf.5.in
doc/tinc.texi
src/connection.h
src/net_setup.c
src/protocol_auth.c
src/route.c

index 8e64445..e2ded36 100644 (file)
@@ -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),
index 3565818..d2b09fa 100644 (file)
@@ -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|no> (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.
index b3a7e33..d5c14bd 100644 (file)
@@ -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 */
index 369c8a4..7d20803 100644 (file)
@@ -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)
index c2df4cd..4707dce 100644 (file)
@@ -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;
index 77bec04..c04b0ad 100644 (file)
@@ -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)