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.
 
 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),
 .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.
 
 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.
 @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_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 */
 
 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;
 
        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)
        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;
 
        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);
        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;
        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,
 
        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_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;
        /* 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) {
 }
 
 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 */
                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;
 
        /* 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)
        /* Search for MSS option header */
        for(int i = 0; i < len;) {
                if(packet->data[start + 20 + i] == 0)