X-Git-Url: https://www.tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=src%2Froute.c;h=e3bcf3bb09ffc302cc135167212c18019fa1abdd;hp=1f91db9729588d128848cbc2951118555c8ad6c5;hb=708314df2f61675d0f54e541c9fff62ac1f433b5;hpb=95a6974de173e0cb78611c6704ed09631d510dae diff --git a/src/route.c b/src/route.c index 1f91db97..e3bcf3bb 100644 --- a/src/route.c +++ b/src/route.c @@ -34,6 +34,7 @@ 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; @@ -49,7 +50,10 @@ static const size_t ip6_size = sizeof(struct ip6_hdr); static const size_t icmp6_size = sizeof(struct icmp6_hdr); static const size_t ns_size = sizeof(struct nd_neighbor_solicit); static const size_t opt_size = sizeof(struct nd_opt_hdr); -#define max(a, b) ((a) > (b) ? (a) : (b)) + +#ifndef MAX +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif /* RFC 1071 */ @@ -216,7 +220,7 @@ void age_subnets(void) { for(node = myself->subnet_tree->head; node; node = next) { next = node->next; s = node->data; - if(s->expires && s->expires < now) { + if(s->expires && s->expires <= now) { ifdebug(TRAFFIC) { char netstr[MAXNETSTR]; if(net2str(netstr, sizeof netstr, s)) @@ -394,10 +398,13 @@ static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) { via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via; - if(via && packet->len > max(via->mtu, 590) && via != myself) { + 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) { - packet->len = max(via->mtu, 590); + packet->len = MAX(via->mtu, 590); route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED); } else { fragment_ipv4_packet(via, packet); @@ -542,9 +549,12 @@ static void route_ipv6_unicast(node_t *source, vpn_packet_t *packet) { via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via; - if(via && packet->len > max(via->mtu, 1294) && via != myself) { + 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); + packet->len = MAX(via->mtu, 1294); route_ipv6_unreachable(source, packet, ICMP6_PACKET_TOO_BIG, 0); return; } @@ -809,6 +819,9 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { // 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); @@ -834,7 +847,7 @@ 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) { + if(forwarding_mode == FMODE_KERNEL && source != myself) { send_packet(myself, packet); return; }