X-Git-Url: https://www.tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=src%2Froute.c;h=853b7f5b1acb5a916ec1657131c598e26768b4ec;hp=664fed89fbd102edb543b637ed7148edaa2009d9;hb=8ae54dc7c782bcc4b771ec0766fcf9eee115756e;hpb=40d91ff619a6ea24a2a35c9d934bcc6bace27e24 diff --git a/src/route.c b/src/route.c index 664fed89..853b7f5b 100644 --- a/src/route.c +++ b/src/route.c @@ -33,6 +33,8 @@ #include "utils.h" rmode_t routing_mode = RMODE_ROUTER; +fmode_t forwarding_mode = FMODE_INTERNAL; +bool directonly = false; bool priorityinheritance = false; int macexpire = 600; bool overwrite_mac = false; @@ -94,9 +96,13 @@ 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 || !(via->options & OPTION_CLAMP_MSS)) + if(!source || !via || !(via->options & OPTION_CLAMP_MSS)) return; + uint16_t mtu = source->mtu; + if(via != myself && via->mtu < mtu) + mtu = via->mtu; + /* Find TCP header */ int start = 0; uint16_t type = packet->data[12] << 8 | packet->data[13]; @@ -140,7 +146,7 @@ static void clamp_mss(const node_t *source, const node_t *via, vpn_packet_t *pac /* Found it */ uint16_t oldmss = packet->data[start + 22 + i] << 8 | packet->data[start + 23 + i]; - uint16_t newmss = via->mtu - start - 20; + uint16_t newmss = mtu - start - 20; uint16_t csum = packet->data[start + 16] << 8 | packet->data[start + 17]; if(oldmss <= newmss) @@ -379,13 +385,19 @@ static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) { } if(!subnet->owner->status.reachable) - route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_UNREACH); + return route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_UNREACH); + + if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) + return route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_ANO); if(priorityinheritance) packet->priority = packet->data[15]; via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via; + if(directonly && subnet->owner != via) + return route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_ANO); + if(via && packet->len > max(via->mtu, 590) && via != myself) { ifdebug(TRAFFIC) logger(LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu); if(packet->data[20] & 0x40) { @@ -527,10 +539,16 @@ static void route_ipv6_unicast(node_t *source, vpn_packet_t *packet) { } if(!subnet->owner->status.reachable) - route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE); + return route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE); + + if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) + return route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN); via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via; + if(directonly && subnet->owner != via) + return route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN); + if(via && packet->len > max(via->mtu, 1294) && via != myself) { ifdebug(TRAFFIC) logger(LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu); packet->len = max(via->mtu, 1294); @@ -792,9 +810,15 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { return; } + if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) + return; + // Handle packets larger than PMTU node_t *via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via; + + if(directonly && subnet->owner != via) + return; if(via && packet->len > via->mtu && via != myself) { ifdebug(TRAFFIC) logger(LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu); @@ -820,6 +844,11 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { } void route(node_t *source, vpn_packet_t *packet) { + if(forwarding_mode == FMODE_KERNEL && source != myself) { + send_packet(myself, packet); + return; + } + if(!checklength(source, packet, ether_size)) return;