Instead of UNIX time, the log messages now start with the time in RFC3339
format, which human-readable and still easy for the computer to parse and sort.
The HUP signal will also cause the log file to be closed and reopened, which is
useful when log rotation is used. If there is an error while opening the log
file, this is logged to stderr.
But we do ignore SIGPIPE, and tinc 1.0.x signals that are no longer used
(SIGUSR1 and SIGUSR2), since the default handler of these signals is to
terminate tincd immediately.
Although we use qsort(), which is not guaranteed to be stable, resorting the
previously sorted array is more stable than recreating and resorting the array
each time.
We live in the 21st century, and we require C99 semantics, so we do not need to
work around buggy libcs. The xmalloc() and related functions are now static
inline functions.
We don't override any signal handlers anymore except those for SIGPIPE and
SIGCHLD. Fatal signals (SIGSEGV, SIGBUS etc.) will terminate tincd and
optionally dump core. The previous behaviour was to terminate gracefully and
try to restart, but that usually failed and made any core dump useless.
This would allow tincctl to connect to a remote tincd, or to a local tincd that
isn't listening on localhost, for example if it is using the BindToInterface or
BindToAddress options.
Also log an error when the input buffer contains more than MAXBUFSIZE bytes
already, instead of silently claiming the other side closed the connection.
Libevent 2.0's buffer code is not completely backward compatible with 1.4's.
In order to not (mis)use it anymore, we implement it ourselves. The buffers
are automatically expanding when necessary. When consuming data from the
buffer, no memmove()s are performed. Only when adding to the buffer would
write past the end do we shift everything back to the start.
In commit 4a21aabada, code was added to detect
contradicting ADD_EDGE and DEL_EDGE messages being sent, which is an indication
of two nodes with the same Name connected to the same VPN. However, these
contradictory messages can also happen when there is a network partitioning. In
the former case a loop happens which causes many contradictory message, while
in the latter case only a few of those messages will be sent. So, now we
increase the threshold to at least 10 of both ADD_EDGE and DEL_EDGE messages.
Since tinc now handles UDP packets with a different source address and port
than used for TCP connections, the heuristic to treat edges as indirect when
tinc could detect that multiple addresses were used does not make sense
anymore, and can actually reduce performance.
Because we don't want to keep track of that, and this will cause the node
structure from being relinked into the node tree, which results in myself
pointing to an invalid address.
When a UDP packet was received with an unknown source address/port, and if it
failed a HMAC check against known keys, it could still incorrectly assign that
UDP address to another node. This would temporarily cause outgoing UDP packets
to go to the wrong destination address, until packets from the correct address
were received again.
Found by cppcheck, which complained about lenin not being initialized, but the
real problem is that reading packets would fail when using code compiled with
--tunemu on a normal tun device.
Before, if MTU probes failed, tinc would stop sending probes until the next
time keys were regenerated (by default, once every hour). Now it continues to
send them every PingInterval, so it recovers faster from temporary failures.
Although transient errors sometimes happen on the tun/tap device (for example,
if the kernel is temporarily out of buffer space), there are situations where
the tun/tap device becomes permanently broken. Instead of endlessly spamming
the syslog, we now sleep an increasing amount of time between consecutive read
errors, and if reads still fail after 10 attempts (approximately 3 seconds),
tinc will quit.
Treat netname "." in a special way as if there was no netname
specified. Before, f.e. tincd -n. -k didn't work as it tried
to open /var/run/tinc-.pid. Now -n. works as if there was no
-n option is specified.
Signed-Off-By: Michael Tokarev <mjt@tls.msk.ru>
With some exceptions, tinc only accepted host configuration options for the
local node from the corresponding host configuration file. Although this is
documented, many people expect that they can also put those options in
tinc.conf. Tinc now internally merges the contents of both tinc.conf and the
local host configuration file.
Options given on the command line have precedence over configuration from files.
This can be useful, for example, for a roaming node, for which 'ConnectTo' and
<host>.Address depends on its location.
In this situation, the two nodes will start fighting over the edges they announced.
When we have to contradict both ADD_EDGE and DEL_EDGE messages, we log a warning,
and with 25% chance per PingTimeout we quit.