X-Git-Url: https://tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=src%2Froute.c;h=829773180c87ab6d549e26b3d3e1577ed1c2499d;hp=5117e92f4f41ca6dbf8554e086fe8de4ebfd2a64;hb=2a538ed34332b3392f866d56accd9efecc9467ed;hpb=e4812ba9cc4262ec921944f02639ce55781d7497 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); }