If one uses a symbolic name for the Port option, tinc will send that name
literally to other nodes. However, it is not guaranteed that all nodes have
the same contents in /etc/services, or have such a file at all.
If a node is unreachable, and not connected to an edge anymore, it gets
deleted. When this happens its subnets are also removed, which should
not happen with StrictSubnets=yes.
Solution:
- do not remove subnets in src/net.c::purge(), we know that all subnets
in the list came from our hosts files.
I think here you got the check wrong by looking at the tunnelserver
code below it - with strictsubnets we still inform others but do not
remove the subnet from our data.
- do not remove nodes in net.c::purge() that still have subnets
attached.
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.
This determines if and how incoming packets that are not meant for the local
node are forwarded. It can either be off, internal (tinc forwards them itself,
as in previous versions), or kernel (packets are always sent to the TUN/TAP
device, letting the kernel sort them out).
When this option is enabled, tinc will not accept dynamic updates of Subnets
from other nodes, but will only use Subnets read from local host config files
to build its routing table.
Instead of allocating storage for each line read, we now read into fixed-size
buffers on the stack. This fixes a case where a malformed configuration file
could crash tinc.
Every operating system seems to have its own, slightly different way to disable
packet fragmentation. Emit a compiler warning when no suitable way is found.
On OpenBSD, it seems impossible to do it for IPv4.
To help peers that are behind NAT connect to each other directly via UDP, they
need to know the exact external address and port that they use. Keys exchanged
between NATted peers necessarily go via a third node, which knows this address
and port, and can append this information to the keys, which is in turned used
by the peers.
Since PMTU discovery will immediately trigger UDP communication from both sides
to each other, this should allow direct communication between peers behind
full, address-restricted and port-restricted cone NAT.
When we got a key request for or from a node we don't know, we disconnected the
node that forwarded us that request. However, especially in TunnelServer mode,
disconnecting does not help. We now ignore such requests, but since there is no
way of telling the original sender that the request was dropped, we now retry
sending REQ_KEY requests when we don't get an ANS_KEY back.
Commit 052ff8b2c5 contained a bug that causes
scripts to be called with an empty, or possibly corrupted SUBNET variable when
a Subnet is added or removed while the owner is still online. In router mode,
this normally does not happen, but in switch mode this is normal.
Before, we immediately retried select() if it returned -1 and errno is EAGAIN
or EINTR, and if it returned 0 it would check for network events even if we
know there are none. Now, if -1 or 0 is returned we skip checking network
events, but we do check for timer and signal events.
One reason to send the ALRM signal is to let tinc immediately try to connect to
outgoing nodes, for example when PPP or DHCP configuration of the outgoing
interface finished. Conversely, when the outgoing interface goes down one can
now send this signal to let tinc quickly detect that links are down too.
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.
For IPv6, the minimum MTU is 1280 (RFC 2460), for IPv4 the minimum is actually
68, but this is such a low limit that it will probably hurt performance, so we
do as if it is 576 (the minimum packet size hosts should be able to handle, RFC
791). If we detect a path MTU smaller than those minima, and we have to handle
a packet that is bigger than the PMTU but smaller than those minima, we forward
them via TCP instead of fragmenting or returning ICMP packets.
We clear the cached address used for UDP connections when a node becomes
unreachable. This also prevents host-up scripts from passing the old, cached
address from when the host becomes reachable again from a different address.
Before it would check all addresses, and not learn an address if another node
already claimed that address. This caused fast roaming to fail, the code from
commit 6f6f426b35 was never triggered.
In switch mode, if a known MAC address is claimed by a second node before it
expired at the first node, it is likely that this is because a computer has
roamed from the LAN of the first node to that of the second node. To ensure
packets for that computer are routed to the second node, the first node should
delete its corresponding Subnet as soon as possible, without waiting for the
normal expiry timeout.
If MTU probing discovered a node was not reachable via UDP, packets for it were
forwarded to the next hop, but always via TCP, even if the next hop was
reachable via UDP. This is now fixed by retrying to send the packet using
send_packet() if the destination is not the same as the nexthop.