From 2a538ed34332b3392f866d56accd9efecc9467ed Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Fri, 15 Jan 2010 13:42:37 +0100 Subject: [PATCH] Clamp MSS of IPv4 SYN packets. Some ISPs block the ICMP Fragmentation Needed packets that tinc sends. We clamp the MSS of IPv4 SYN packets to prevent hosts behind those ISPs from sending too large packets. --- src/route.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/route.c b/src/route.c index 5117e92f..82977318 100644 --- a/src/route.c +++ b/src/route.c @@ -93,6 +93,53 @@ static bool checklength(node_t *source, vpn_packet_t *packet, length_t length) { return true; } +void clamp_mss(node_t *source, node_t *via, vpn_packet_t *packet) { + int i; + int len = ((packet->data[46] >> 4) - 5) * 4; + + for(int i = 0; i < len;) { + if(packet->data[54 + i] == 0) + break; + + if(packet->data[54 + i] == 1) { + i++; + continue; + } + + if(i > len - 2 || i > len - packet->data[55 + i]) + break; + + if(packet->data[54 + i] != 2) { + if(packet->data[55 + i] < 2) + break; + i += packet->data[55 + i]; + continue; + } + + if(packet->data[55] != 4) + break; + + uint16_t oldmss = packet->data[56 + i] << 8 | packet->data[57 + i]; + uint16_t newmss = via->mtu - 54; + uint16_t csum = packet->data[50] << 8 | packet->data[51]; + + if(oldmss <= newmss) + break; + + ifdebug(TRAFFIC) logger(LOG_INFO, "Clamping MSS of packet from %s to %s to %d", source->name, via->name, newmss); + + packet->data[56 + i] = newmss >> 8; + packet->data[57 + i] = newmss & 0xff; + csum ^= 0xffff; + csum -= oldmss; + csum += newmss; + csum ^= 0xffff; + packet->data[50] = csum >> 8; + packet->data[51] = csum & 0xff; + break; + } +} + static void swap_mac_addresses(vpn_packet_t *packet) { mac_t tmp; memcpy(&tmp, &packet->data[0], sizeof tmp); @@ -328,6 +375,9 @@ static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) { return; } + if(via && via != myself && packet->data[23] == 6 && packet->len >= 58 && (packet->data[46] >> 4) > 5) + clamp_mss(source, via, packet); + send_packet(subnet->owner, packet); } @@ -740,6 +790,9 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { } } + if(via && via != myself && (packet->data[12] << 8 | packet->data[13]) == ETH_P_IP && packet->len >= 58 && packet->data[23] == 6 && (packet->data[46] >> 4) > 5) + clamp_mss(source, via, packet); + send_packet(subnet->owner, packet); } -- 2.20.1