During the path MTU discovery phase, we might not know the maximum MTU yet, but
we do know a safe minimum. If we encounter a packet that is larger than that
the minimum, we now send it via TCP instead to ensure it arrives. We also
allow large packets that we cannot fragment or create ICMP replies for to be
sent via TCP.
The TAP-Win32 device is not a socket, and select() under Windows only works
with sockets. Tinc used a separate thread to read from the TAP-Win32 device,
and passed this via a local socket to the main thread which could then select()
from it. We now use a global mutex, which is only unlocked when the main thread
is waiting for select(), to allow the TAP reader thread to process packets
directly.
In light of the recent improvements of attacks on SHA1, the default hash
algorithm in tinc is now SHA256. At the same time, the default symmetric
encryption algorithm has been changed to AES256.
This allows us to use getaddrinfo(), getnameinfo() and related functions, which
allow tinc to make connections over existing IPv6 networks. These functions are
not available on Windows 2000 however. By default, support is enabled, but when
compiling for Windows 2000 the configure switch --with-windows2000 should be
used.
Since getaddrinfo() et al. are not functions but macros on Windows, we have to
use AC_CHECK_DECLS() instead of AC_CHECK_FUNCS() in configure.in.
We used both rand() and random() in our code. Since it returns an int, we have
to use %x in our format strings instead of %lx. This fixes a crash under
Windows when cross-compiling tinc with a recent version of MinGW.
If two pointers do not belong to the same array, pointer subtraction gives
nonsensical results, depending on the level of optimisation and the
architecture one is compiling for. It is apparently not just subtracting the
pointer values and dividing by the size of the object, but uses some kind of
higher magic not intended for mere mortals. GCC will not warn about this at
all. Casting to void * is also a no-no, because then GCC does warn that strict
aliasing rules are being broken. The only safe way to query the ordering of two
pointers is to use the (in)equality operators.
The unsafe implementation of connection_compare() has probably caused the "old
connection_t for ... still lingering" messages. Our implementation of AVL trees
is augmented with a doubly linked list, which is normally what is traversed.
Only when deleting an old connection the tree itself is traversed.
If PMTUDiscovery is enabled, and we see a unicast packet that is larger than
the path MTU in switch mode, treat it just like we would do in router mode.
PMTUDiscovery was disabled in commit d5b56bbba5
because tinc did not handle packets larger than the path MTU in switch and hub
modes. We now allow it again in preparation of proper support, but default to
off.
Commit 5674bba5c5 introduced weighted Subnets,
but the weight was included in the SUBNET variable passed to subnet-up/down
scripts. This makes it harder to use in those scripts. The weight is now
stripped from the SUBNET variable and put in the WEIGHT variabel.
Grzegorz Dymarek noted that tinc segfaults at the stat() call in
execute_script() on the iPhone. We can omit the stat() call for the moment,
the subsequent call to system() will fail with just a warning.
This is a slightly modified patch from Grzegorz Dymarek that allows tinc to use
the tunemu device, which allows tinc to be compiled for iPhones and recent
iPods. To enable support for tunemu, the --enable-tunemu option has to be used
when running the configure script.
Tinc is licensed under the GPL version 2 or later. To ensure autoconf does not
install the wrong license if COPYING is missing, we have to put the right one
in place.
These functions wrap asprintf() and vasprintf(), and check the return value. If
the function failed, tinc will exit with an error message, similar to xmalloc()
and friends.
Valgrind caught tinc reading free'd memory during a purge(). This was caused by
first removing it from the main node tree, which will already call free_node(),
and then removing it from the UDP tree. This might cause spurious segmentation
faults.
Although we select() before we call recvfrom(), it sometimes happens that
select() tells us we can read but a subsequent read fails anyway. This is
harmless.
If there is an outstanding MTU probe event for a node which is not reachable
anymore, a UDP packet would be sent to that node, which caused a key request to
be sent to that node, which triggered a NULL pointer dereference. Probes and
other UDP packets to unreachable nodes are now dropped.
When chrooted, we either need to force-initialize resolver
and/or nsswitch somehow (no clean way) or resolve all the
names we want before entering chroot jail. The latter
looks cleaner, easier and it is actually safe because
we still don't talk with the remote nodes there, only
initiating outgoing connections.
This option can be set to low, normal or high. On UNIX flavours, this changes
the nice value of the process by +10, 0 and -10 respectively. On Windows, it
sets the priority to BELOW_NORMAL_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS and
HIGH_PRIORITY_CLASS respectively.
A high priority might help to reduce latency and packet loss on the VPN.
If a host has multiple addresses on an interface, the source address of the TCP
connection(s) was picked by the operating system while the UDP packets used a
bound socket, i. e. the source address was the address specified by the user.
This caused problems because the receiving code requires the TCP connection and
the UDP connection to originate from the same IP address.
This patch adds support for the `BindToInterface' and `BindToAddress' options
to the setup of outgoing TCP connections.
Tested with Debian Etch on x86 and Debian Lenny on x86_64.
Signed-off-by: Florian Forster <octo@verplant.org>
If running without `--net', the (global) variable `netname' is NULL. This
creates a segmentation fault because this NULL-pointer is passed to strdup:
Program terminated with signal 11, Segmentation fault.
#0 0xb7d30463 in strlen () from /lib/tls/i686/cmov/libc.so.6
(gdb) bt
#0 0xb7d30463 in strlen () from /lib/tls/i686/cmov/libc.so.6
#1 0xb7d30175 in strdup () from /lib/tls/i686/cmov/libc.so.6
#2 0x0805bf47 in xstrdup (s=0x0) at xmalloc.c:118 <---
#3 0x0805be33 in setup_device () at device.c:66
#4 0x0805072e in setup_myself () at net_setup.c:432
#5 0x08050db2 in setup_network () at net_setup.c:536
#6 0x0805b27f in main (argc=Cannot access memory at address 0x0) at tincd.c:580
This patch fixes this by checking `netname' in `setup_device'. An alternative
would be to check for NULL-pointers in `xstrdup' and return NULL in this case.
Signed-off-by: Florian Forster <octo@verplant.org>
Add some logging about refused ADD_SUBNET
(it causes subsequent client disconnect so it's
important to know which subnet was at fault).
Maybe we should just ignore it completely.
First of all, the idea behind the TunnelServer option is to hide all other
nodes from each other, so we shouldn't forward broadcast packets from them
anyway. The other reason is that since edges from other nodes are ignored, the
calculated minimum spanning tree might not be correct, which can result in
routing loops.
Since compression can either grow or shrink a packet, the size of an MTU probe
after decompression might not reflect the real path MTU. Now we use the size
before decompression, which is independent of the compression algorithm, and
substract a safety margin such that the calculated path MTU will be safe even
for packets which grow as much as possible after compression.