diff --git a/doc/tinc.conf.5.in b/doc/tinc.conf.5.in index 797ca522..8f5237f7 100644 --- a/doc/tinc.conf.5.in +++ b/doc/tinc.conf.5.in @@ -199,6 +199,12 @@ Tinc will expect packets read from the virtual network device to start with an Ethernet header. .El +.It Va DirectOnly Li = yes | no Pq no +When this option is enabled, packets that cannot be sent directly to the destination node, +but which would have to be forwarded by an intermediate node, are dropped instead. +When combined with the IndirectData option, +packets for nodes for which we do not have a meta connection with are also dropped. + .It Va Forwarding Li = off | internal | kernel Pq internal This option selects the way indirect packets are forwarded. .Bl -tag -width indent diff --git a/doc/tinc.texi b/doc/tinc.texi index 091b5e7a..0ea421e3 100644 --- a/doc/tinc.texi +++ b/doc/tinc.texi @@ -818,6 +818,13 @@ Tinc will expect packets read from the virtual network device to start with an Ethernet header. @end table +@cindex DirectOnly +@item DirectOnly = (no) +When this option is enabled, packets that cannot be sent directly to the destination node, +but which would have to be forwarded by an intermediate node, are dropped instead. +When combined with the IndirectData option, +packets for nodes for which we do not have a meta connection with are also dropped. + @cindex Forwarding @item Forwarding = (internal) This option selects the way indirect packets are forwarded. diff --git a/src/net_setup.c b/src/net_setup.c index 6e51b2e2..867fef94 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -339,6 +339,7 @@ bool setup_myself(void) { if(myself->options & OPTION_TCPONLY) myself->options |= OPTION_INDIRECT; + get_config_bool(lookup_config(config_tree, "DirectOnly"), &directonly); get_config_bool(lookup_config(config_tree, "StrictSubnets"), &strictsubnets); get_config_bool(lookup_config(config_tree, "TunnelServer"), &tunnelserver); strictsubnets |= tunnelserver; diff --git a/src/route.c b/src/route.c index 1f91db97..4e7f7e58 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; @@ -394,6 +395,9 @@ static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) { 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) { @@ -542,6 +546,9 @@ static void route_ipv6_unicast(node_t *source, vpn_packet_t *packet) { 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); @@ -809,6 +816,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); diff --git a/src/route.h b/src/route.h index aa25dcf5..49431f20 100644 --- a/src/route.h +++ b/src/route.h @@ -38,6 +38,7 @@ typedef enum fmode_t { extern rmode_t routing_mode; extern fmode_t forwarding_mode; +extern bool directonly; extern bool overwrite_mac; extern bool priorityinheritance; extern int macexpire;