Commit graph

118 commits

Author SHA1 Message Date
thorkill
4be26caf4e Merge remote-tracking branch 'guus/1.1' into thkr-foor2Vup 2016-05-08 15:58:29 +02:00
Guus Sliepen
2055c3e21d AutoConnect now only chooses from nodes for which we know an address.
Based partially on work from Rafał Leśniak.
2016-04-30 20:11:55 +02:00
thorkill
e95c1a93a7 Merge with guus/1.1 2015-11-06 22:56:46 +01:00
Guus Sliepen
543c0abbd9 Fix struct node_status_t.
Although not a problem for tinc internally, the size of the struct was 12
bytes instead of 4, causing some problems when interpreting the value
received from tincd by the CLI.
2015-09-25 10:05:24 +02:00
thorkill
618ddadeab Fixed a segfault when all nodes available for autoconnect has been exhausted
In cases when tinc has all available nodes in outgoing connections and
can not establish those connection due to network outage periodic_handler()
would crash since tmp_node_tree->count is 0.

This commit adds also new flag node->status.has_cfg_address to prevent
update_udp_address() from removing this flag.

Fixed node_status_t->unused - 13 + 19 = 32
2015-07-23 20:46:20 +02:00
thorkill
3c67735720 Make autoconnect faster
When AutoConnect is enabled tinc tries to connect to other nodes picking them at random.
This may be sane default behavior but it may take ages if only few nodes have
defined Address in thier config.

Proposed solution to this problem:
- Filter out nodes without known address in periodic_handler
  I have added new node->status.has_known_address bool
- On update_node_udp() update this flag
2015-07-23 18:02:30 +02:00
Guus Sliepen
d150e82b94 Fix crash is sptps_logger().
Unfortunately, sptps_logger() cannot know if s->handle is pointing to a
connection_t or a node_t. But it needs to print name and hostname in
both cases. So make sure both types have name and hostname fields at the
start with the same offset.
2015-06-26 20:11:31 +02:00
Guus Sliepen
45a46f068c Fix crash is sptps_logger().
Unfortunately, sptps_logger() cannot know if s->handle is pointing to a
connection_t or a node_t. But it needs to print name and hostname in
both cases. So make sure both types have name and hostname fields at the
start with the same offset.
2015-06-10 23:42:17 +02:00
Etienne Dechamps
76a9be5bce Throttle the rate of MTU_INFO messages.
This makes sure MTU_INFO messages are only sent at the maximum rate of
5 per second (by default). As usual with these "probe" mechanisms, the
rate of these messages cannot be higher than the rate of data packets
themselves, since they are sent from the RX path.
2015-03-14 13:39:05 +00:00
Etienne Dechamps
467397f25d Throttle the rate of UDP_INFO messages.
This makes sure UDP_INFO messages are only sent at the maximum rate of
5 per second (by default). As usual with these "probe" mechanisms, the
rate of these messages cannot be higher than the rate of data packets
themselves, since they are sent from the RX path.
2015-03-14 13:39:05 +00:00
Guus Sliepen
ae5b56c03d Send gratuitous type 2 probe replies.
If we receive any traffic from another node, we periodically send back a
gratuitous type 2 probe reply with the maximum received packet length.
On the other node, this causes the udp and perhaps mtu probe timers to
be reset, so it does not need to send a probe request. Gratuitous probe
replies from another node also count as received traffic for this
purpose, so for nodes that also have a meta-connection, UDP keepalive
packets in principle can now solely be type 2 replies. This reduces the
amount of probe traffic even more.

To work, gratuitous replies should be sent slightly more often than
udp_discovery_keepalive_interval, so probe requests won't be triggered.
This also means that the timer resolution must be smaller than the
difference between the two, and at the moment it's kind of a hack.
2015-01-11 17:44:50 +01:00
Guus Sliepen
f0afde0467 Keep track of the largest UDP packet size received from a node. 2015-01-11 16:10:58 +01:00
Guus Sliepen
088b5fd9ee Remove RTT and packet loss estimation code.
This is not working at all anymore. Just remove it, and we'll do another
attempt at RTT, bandwidth and packet loss estimation after the new
probing code stabilizes.
2015-01-11 14:44:15 +01:00
Guus Sliepen
6056f1c13b Remember whether we sent our key to another node.
In tinc 1.0.x, this was tracked in node->inkey, however in tinc 1.1 we have an abstraction layer for
the legacy cipher and digest, and we don't keep an explicit copy of the key around. We cannot use
cipher_active() or digest_active(), since it is possible to set both to the null algorithm. So add a bit to
node_status_t.
2015-01-10 22:26:33 +01:00
Etienne Dechamps
c22560ae32 Remove bandwidth estimation code.
tinc bandwidth estimation has always been quite unreliable (at least in
my experience), but there's no chance of it working anymore since the
last changes to MTU discovery code, because packets are not sent in
batches of three anymore.

This commit removes the dead code - fortunately, nothing depends on this
estimation (it's not even shown in node info). We probably need be
smarter about this if we do want this estimation back.
2015-01-02 09:55:09 +00:00
Etienne Dechamps
98716a227e Move PMTU discovery code into the TX path.
Currently, the PMTU discovery code is run by a timeout callback,
independently of tunnel activity. This commit moves it into the TX
path, meaning that send_mtu_probe_handler() is only called if a
packet is about to be sent. Consequently, it has been renamed to
try_mtu() for consistency with try_tx(), try_udp() and try_sptps().

Running PMTU discovery code only as part of the TX path prevents
PMTU discovery from generating unreasonable amounts of traffic when
the "real" traffic is negligible. One extreme example is sending one
real packet and then going silent: in the current code this one little
packet will result in the entire PMTU discovery algorithm being run
from start to finish, resulting in absurd write traffic amplification.
With this patch, PMTU discovery stops as soon as "real" packets stop
flowing, and will be no more aggressive than the underlying traffic.

Furthermore, try_mtu() only runs if there is confirmed UDP
connectivity as per the UDP discovery mechanism. This prevents
unnecessary network chatter - previously, the PMTU discovery code
would send bursts of (potentially large) probe packets every second
even if there was nothing on the other side. With this patch, the
PMTU code only does that if something replied to the lightweight UDP
discovery pings.

These inefficiencies were made even worse when the node is not a
direct neighbour, as tinc will use PMTU discovery both on the
destination node *and* the relay. UDP discovery is more lightweight for
this purpose.

As a bonus, this code simplifies overall code somewhat - state is
easier to manage when code is run in predictable contexts as opposed
to "surprise callbacks". In addition, there is no need to call PMTU
discovery code outside of net_packet.c anymore, thereby simplifying
module boundaries.
2015-01-01 17:40:15 +00:00
Etienne Dechamps
7939ee1283 Add UDP discovery mechanism.
This adds a new mechanism by which tinc can determine if a node is
reachable via UDP. The new mechanism is currently redundant with the
PMTU discovery mechanism - that will be fixed in a future commit.

Conceptually, the UDP discovery mechanism works similarly to PMTU
discovery: it sends UDP probes (of minmtu size, to make sure the tunnel
is fully usable), and assumes UDP is usable if it gets replies. It
assumes UDP is broken if too much time has passed since the last reply.

The big difference with the current PMTU discovery mechanism, however,
is that UDP discovery probes are only triggered as part of the
packet TX path (through try_tx()). This is quite interesting, because
it means tinc will never send UDP pings more often than normal packets,
and most importantly, it will automatically stop sending pings as soon
as packets stop flowing, thereby nicely reducing network chatter.

Of course, there are small drawbacks in some edge cases: for example,
if a node only sends one packet every minute to another node, these
packets will only be sent over TCP, because the interval between packets
is too long for tinc to maintain the UDP tunnel. I consider this a
feature, not a bug: I believe it is appropriate to use TCP in scenarios
where traffic is negligible, so that we don't pollute the network with
pings just to maintain a UDP tunnel that's seeing negligible usage.
2015-01-01 17:40:15 +00:00
Guus Sliepen
cfe9285adf Allow tinc to be compiled without OpenSSL.
The option "--disable-legacy-protocol" was added to the configure
script. The new protocol does not depend on any external crypto
libraries, so when the option is used tinc is no longer linked to
OpenSSL's libcrypto.
2014-12-29 22:57:18 +01:00
Etienne Dechamps
55a78da4e0 Introduce node IDs.
This introduces a new type of identifier for nodes, which complements
node names: node IDs. Node IDs are defined as the first 6 bytes of the
SHA-256 hash of the node name. They will be used in future code in lieu
of node names as unique node identifiers in contexts where space is at
a premium (such as VPN packets).

The semantics of node IDs is that they are supposed to be unique in a
tinc graph; i.e. two different nodes that are part of the same graph
should not have the same ID, otherwise things could break. This
solution provides this guarantee based on realistic probabilities:
indeed, according to the birthday problem, with a 48-bit hash, the
probability of at least one collision is 1e-13 with 10 nodes, 1e-11
with 100 nodes, 1e-9 with 1000 nodes and 1e-7 with 10000 nodes. Things
only start getting hairy with more than 1 million nodes, as the
probability gets over 0.2%.
2014-10-04 11:13:59 +01:00
Etienne Dechamps
e16ade874d Use edge local addresses for local discovery.
This introduces a new way of doing local discovery: when tinc has
local address information for the recipient node, it will send local
discovery packets directly to the local address of that node, instead
of using broadcast packets.

This new way of doing local discovery provides numerous advantages compared to
using broadcasts:

 - No broadcast packets "polluting" the local network;

 - Reliable even if the sending host has multiple network interfaces (in
   contrast, broadcasts will only be sent through one unpredictable
   interface)

 - Works even if the two hosts are not on the same broadcast domain. One
   example is a large LAN where the two hosts might be on different local
   subnets. In fact, thanks to UDP hole punching this might even work if
   there is a NAT sitting in the middle of the LAN between the two nodes!

 - Sometimes a node is reachable through its "normal" address, and via a
   local subnet as well. One might think the local subnet is the best route
   to the node in this case, but more often than not it's actually worse -
   one example is where the local segment is a third party VPN running in
   parallel, or ironically it can be the local segment formed by the tinc
   VPN itself! Because this new algorithm only checks the addresses for
   which an edge is already established, it is less likely to fall into
   these traps.
2014-06-29 11:23:32 +01:00
Guus Sliepen
3d41e7d712 Make LocalDiscovery work for SPTPS packets. 2013-11-21 22:13:14 +01:00
Guus Sliepen
9b9230a0a7 Use conditional compilation for cryptographic functions.
This gets rid of the rest of the symbolic links. However, as a consequence, the
crypto header files have now moved to src/, and can no longer contain
library-specific declarations. Therefore, cipher_t, digest_t, ecdh_t, ecdsa_t
and rsa_t are now all opaque types, and only pointers to those types can be
used.
2013-05-01 17:17:22 +02:00
Guus Sliepen
cc3c69c892 Releasing 1.1pre5. 2013-01-20 21:03:22 +01:00
Guus Sliepen
61275547cd Estimate RTT, bandwidth and packet loss between nodes.
Without adding any extra traffic, we can measure round trip times, estimate the
bandwidth and packet loss between nodes. The RTT and bandwidth can be measured
by timing the MTU probe packets. The RTT is the difference between the time a
burst of MTU probes was sent and when the first reply is received. The
bandwidth can be estimated by multiplying the size of the probe packets by the
time between succesive received probe replies of the same burst. The packet
loss can be estimated for incoming traffic by comparing how many packets have
actually been received to the increase in the sequence numbers.

The estimates are not perfect. Especially bandwidth is difficult to measure,
the only accurate way is to continuously send as much data as possible, but
that is obviously not desirable. The packet loss rate is also almost always
a few percent when sending a lot of data over the VPN via TCP, since TCP
*needs* packet loss to work properly.
2013-01-16 16:31:56 +01:00
Guus Sliepen
eef25266cb Count the number of correctly received UDP packets.
Keep track of the number of correct, non-replayed UDP packets that have been
received, regardless of their content. This can be compared to the sequence
number to determine the real packet loss.
2013-01-15 13:33:16 +01:00
Guus Sliepen
6bc5d626a8 Drop libevent and use our own event handling again.
There are several reasons for this:

- MacOS/X doesn't support polling the tap device using kqueue, requiring a
  workaround to fall back to select().
- On Windows only sockets are properly handled, therefore tinc uses a second
  thread that does a blocking ReadFile() on the TAP-Win32/64 device. However,
  this does not mix well with libevent.
- Libevent, event just the core, is quite large, and although it is easy to get
  and install on many platforms, it can be a burden.
- Libev is more lightweight and seems technically superior, but it doesn't
  abstract away all the platform differences (for example, async events are not
  supported on Windows).
2012-11-29 12:28:23 +01:00
Guus Sliepen
d917c8cb6b Fix whitespace. 2012-10-10 17:17:49 +02:00
Guus Sliepen
58f4b845b9 Try all known addresses of node during the PMTU discovery phase.
This helps in situations where some nodes have IPv6 and others have not.
2012-10-10 14:46:22 +02:00
Guus Sliepen
bb6b97ce34 Make datagram SPTPS key exchange more robust.
Similar to old style key exchange requests, keep track of whether a key
exchange is already in progress and how long it took. If no key is known yet
or if key exchange takes too long, (re)start a new key exchange.
2012-10-07 13:31:19 +02:00
Guus Sliepen
9ade39b7d5 Keep last known address and time since reachability changed.
This allows tincctl info to show since when a node is online or offline.
2012-09-26 22:20:43 +02:00
Guus Sliepen
90f1cba1fd Replace node_udp_tree with a hash table. 2012-09-05 13:05:48 +02:00
Guus Sliepen
7a71d48009 Use a status bit to track which nodes use SPTPS. 2012-07-31 21:43:49 +02:00
Guus Sliepen
153abaa4d9 Use datagram SPTPS for packet exchange between nodes.
When two nodes which support SPTPS want to send packets to each other, they now
always use SPTPS. The node initiating the SPTPS session send the first SPTPS
packet via an extended REQ_KEY messages. All other handshake messages are sent
using ANS_KEY messages. This ensures that intermediate nodes using an older
version of tinc can still help with NAT traversal. After the authentication
phase is over, SPTPS packets are sent via UDP, or are encapsulated in extended
REQ_KEY messages instead of PACKET messages.
2012-07-30 18:36:59 +02:00
Guus Sliepen
68a20876d0 Use minor protocol version to determine whether to use ECDH key exchange between nodes. 2012-07-20 01:02:51 +02:00
Guus Sliepen
86c2990327 Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1
Conflicts:
	NEWS
	README
	configure.in
	src/Makefile.am
	src/conf.c
	src/conf.h
	src/connection.c
	src/net.c
	src/tincd.c
2012-03-25 23:35:31 +01:00
Guus Sliepen
4712d8f92e Update copyright notices. 2012-03-10 13:23:08 +01:00
Guus Sliepen
f5dc136cfd Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1
Conflicts:
	src/net.c
	src/net_packet.c
	src/net_socket.c
2012-02-23 13:26:01 +01:00
Guus Sliepen
5a28aa7b8b Add LocalDiscovery option which tries to detect peers on the local network.
Currently, this is implemented by sending IPv4 broadcast packets to the
LAN during path MTU discovery.
2012-02-22 23:17:43 +01:00
Guus Sliepen
3fba80174d Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1
Conflicts:
	NEWS
	README
	configure.in
	doc/tincd.8.in
	src/Makefile.am
	src/bsd/device.c
	src/connection.c
	src/connection.h
	src/cygwin/device.c
	src/device.h
	src/dropin.h
	src/linux/device.c
	src/mingw/device.c
	src/net.c
	src/net_packet.c
	src/net_setup.c
	src/net_socket.c
	src/process.c
	src/protocol.c
	src/protocol_key.c
	src/raw_socket_device.c
	src/route.c
	src/solaris/device.c
	src/tincd.c
	src/uml_device.c
2012-02-22 14:23:59 +01:00
Guus Sliepen
6455654d26 Send packets back using the same socket as they were received on. 2012-02-18 11:48:21 +01:00
Guus Sliepen
cff27a258f Use ECDSA to sign ECDH key exchange for UDP session keys.
The ECDSA public keys will also be included in the ANS_KEY requests,
but are only used when no ECDSA public key is known yet.
2011-07-16 20:21:44 +02:00
Guus Sliepen
8dfa072733 Support ECDH key exchange.
REQ_KEY requests have an extra field indicating key exchange version.
If it is present and > 0, the sender supports ECDH. If the receiver also
does, then it will generate a new keypair and sends the public key in a
ANS_KEY request with "ECDH:" prefixed. The ans_key_h() function will
compute the shared secret, which, at the moment,is used as is to set the
cipher and HMAC keys. However, this must be changed to use a proper KDF.
In the future, the ECDH key exchange must also be signed.
2011-07-03 13:17:28 +02:00
Guus Sliepen
33f241d978 Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1
Conflicts:
	NEWS
	configure.in
	doc/tincd.8.in
	lib/pidfile.c
	lib/pidfile.h
	lib/xalloc.h
	lib/xmalloc.c
	src/conf.c
	src/conf.h
	src/connection.c
	src/connection.h
	src/event.c
	src/graph.c
	src/graph.h
	src/net.c
	src/net.h
	src/node.h
	src/openssl/crypto.c
	src/process.c
	src/protocol.c
	src/protocol_key.c
	src/route.c
2011-06-06 20:42:15 +02:00
Guus Sliepen
64771f73eb Remove a few unnecessary #includes.
Some spotted by Michael Tokarev.
2011-05-28 23:46:56 +02:00
Guus Sliepen
6d08eb1614 Fix sparse warnings and add an extra sprinkling of const.
This is more or less the equivalent of Sven-Haegar Koch's fixes in the 1.1
branch.
2011-05-28 23:36:52 +02:00
Sven-Haegar Koch
b995243ac3 sparse fixup: error: dubious one-bit signed bitfield 2011-05-28 15:24:39 +02:00
Guus Sliepen
8de8f1d9e2 Fix some compiler warnings. 2011-05-17 10:58:22 +02:00
Guus Sliepen
f5843e7d64 Add per-node traffic counters. 2011-05-15 00:42:29 +02:00
Guus Sliepen
886a6f61a1 Merge branch 'master' into 1.1
Conflicts:
	src/net_packet.c
	src/openssl/rsagen.h
	src/protocol_auth.c
	src/protocol_key.c
2010-11-19 12:22:48 +00:00
Brandon L Black
0d61d4ae13 Improved handling of queue-jumping packets on receive 2010-11-13 21:25:48 +01:00