Import Upstream version 1.1~pre4
This commit is contained in:
parent
34d5939212
commit
ff64081061
48 changed files with 1739 additions and 1176 deletions
264
ChangeLog
264
ChangeLog
|
@ -1,3 +1,267 @@
|
||||||
|
commit 5b7f42bca4dbfee7a5fa2bc119f4739baaeb2f55
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Wed Dec 5 22:32:10 2012 +0100
|
||||||
|
|
||||||
|
Releasing 1.1pre4.
|
||||||
|
|
||||||
|
commit 4c16094e949e1f17461ac744118076a3cec437e8
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Wed Dec 5 21:42:43 2012 +0100
|
||||||
|
|
||||||
|
Fix whitespace.
|
||||||
|
|
||||||
|
commit 4f8abf1b29b117c5d593bfa7703966fd88e9eace
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Wed Dec 5 21:40:49 2012 +0100
|
||||||
|
|
||||||
|
Scale packet counters similar to byte counters.
|
||||||
|
|
||||||
|
commit d5f0ff5df86d06825110527ddc252b1268e31479
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Wed Dec 5 21:33:01 2012 +0100
|
||||||
|
|
||||||
|
Don't use nested functions.
|
||||||
|
|
||||||
|
This allows tinc to be compiled with Clang.
|
||||||
|
|
||||||
|
commit eb80105ea855f2c7ee0ea467574acf86cf455a77
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Wed Dec 5 14:42:21 2012 +0100
|
||||||
|
|
||||||
|
Fix compiler warnings on OpenBSD.
|
||||||
|
|
||||||
|
commit 5e3607b616538eac7bb70d78d4f20d847a1c3064
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Mon Dec 3 13:09:40 2012 +0100
|
||||||
|
|
||||||
|
Remove GraphDumpFile from the manual and manpages.
|
||||||
|
|
||||||
|
This option is not supported in tinc 1.1, "tincctl dump graph" can be used
|
||||||
|
instead.
|
||||||
|
|
||||||
|
commit a717b9bcfbe811787fd6718fb3f8fb3f272bcfb9
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Mon Dec 3 13:08:03 2012 +0100
|
||||||
|
|
||||||
|
Add option to dump only a list of reachable nodes.
|
||||||
|
|
||||||
|
commit 75c619e372f02f8225d158fd514f01bd04857d3b
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Mon Dec 3 10:41:28 2012 +0100
|
||||||
|
|
||||||
|
More fixes for Windows.
|
||||||
|
|
||||||
|
In particular, Windows does support many of the timer* macros, except timeradd
|
||||||
|
and timersub.
|
||||||
|
|
||||||
|
commit d53384c2de6d2824b9adcec111301d86e6b25f8e
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Mon Dec 3 09:08:21 2012 +0100
|
||||||
|
|
||||||
|
Fix compiler error on Windows.
|
||||||
|
|
||||||
|
commit 76816e119b7d38a14823d430aafeff362dfbfd41
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Mon Dec 3 09:07:23 2012 +0100
|
||||||
|
|
||||||
|
Fix crash in timeout handling.
|
||||||
|
|
||||||
|
commit d19b00606576d19ef206e363ac709daf3bd00f25
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Mon Dec 3 09:02:08 2012 +0100
|
||||||
|
|
||||||
|
Set a node's pointers to zero before trying to insert it into a tree.
|
||||||
|
|
||||||
|
commit d2b19be1a0dd3c4987aa926117f5bf281892c78b
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Thu Nov 29 14:35:08 2012 +0100
|
||||||
|
|
||||||
|
Fix use of unitialised values in hash tables.
|
||||||
|
|
||||||
|
Not only was Valgrind unhappy about it, it could also result in cache misses.
|
||||||
|
|
||||||
|
commit d9c70767aa6da8b62b4a1034d5f07892603beddd
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Thu Nov 29 14:32:12 2012 +0100
|
||||||
|
|
||||||
|
Fix check for expired events.
|
||||||
|
|
||||||
|
This would trigger a infinite loop if a timeout expired and the next timeout
|
||||||
|
was not expired yet, but less than 1 second from being expired.
|
||||||
|
|
||||||
|
commit 8825cddd0d8ed6dad00924ef382139da51ca3fc4
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Thu Nov 29 12:37:04 2012 +0100
|
||||||
|
|
||||||
|
Allow multiple timeouts to expire at the exact same time.
|
||||||
|
|
||||||
|
commit 6bc5d626a8726fc23365ee705761a3c666a08ad4
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Thu Nov 29 12:28:23 2012 +0100
|
||||||
|
|
||||||
|
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).
|
||||||
|
|
||||||
|
commit d30b9e1272fef18070d37d10b2b3e4bb2fc07f59
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Mon Nov 19 14:20:50 2012 +0100
|
||||||
|
|
||||||
|
Ensure MTU probe replies are sent back the same way they came in.
|
||||||
|
|
||||||
|
Also sprinkle some comments over mtu_probe_h().
|
||||||
|
|
||||||
|
commit 3c1b7047332f4b5e9d5ae7109e696b33712a5fb2
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Mon Nov 19 13:50:17 2012 +0100
|
||||||
|
|
||||||
|
Improve UDP address selection.
|
||||||
|
|
||||||
|
We don't need to search the whole edge tree, we can use the node's own edge
|
||||||
|
tree since each edge has a pointer to its reverse. Also, we do need to make
|
||||||
|
sure we try the reflexive address often.
|
||||||
|
|
||||||
|
commit f57129ce3439f3826c12f15feb5df05e5ad8cab9
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Sat Nov 17 22:48:06 2012 +0100
|
||||||
|
|
||||||
|
Try all known addresses of node during PMTU discovery, now also for SPTPS.
|
||||||
|
|
||||||
|
commit 30404650b28bf72d0b05b55393f2dd492434f9f3
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Sat Nov 17 22:14:52 2012 +0100
|
||||||
|
|
||||||
|
Choose a suitable socket when updating a node's UDP address.
|
||||||
|
|
||||||
|
commit 8f9ee895224b39347783f3119343efc3bdaa3511
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Thu Nov 15 11:24:18 2012 +0100
|
||||||
|
|
||||||
|
Also don't use poll() on MacOS/X.
|
||||||
|
|
||||||
|
commit 8a77df9e28114cbfd83351070fdb266cf31fc310
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Thu Nov 15 11:13:40 2012 +0100
|
||||||
|
|
||||||
|
Disable support for kqueue on MacOS/X.
|
||||||
|
|
||||||
|
Apparently MacOS/X doesn't support kqueue events on character devices.
|
||||||
|
|
||||||
|
commit 818c92e6583006bf2e38f1027044925df6cf0ca0
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Wed Nov 14 10:44:35 2012 +0100
|
||||||
|
|
||||||
|
Remove text saying you must have one of PrivateKey or PrivateKeyFile in tinc.conf.
|
||||||
|
|
||||||
|
commit e8bf81794f412b27261be0f2aa4eb287352041af
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Tue Nov 13 15:05:41 2012 +0100
|
||||||
|
|
||||||
|
Send broadcast packets using a random socket, and properly support IPv6.
|
||||||
|
|
||||||
|
Before it would always use the first socket, and always send an IPv4 broadcast packet. That
|
||||||
|
works fine in a lot of situations, but it is better to try all sockets, and to send IPv6 packets
|
||||||
|
on IPv6 sockets. This is especially important for users that are on IPv6-only networks or that
|
||||||
|
have multiple physical network interfaces, although in the latter case it probably requires
|
||||||
|
them to use the ListenAddress variable to create a separate socket for each interface.
|
||||||
|
|
||||||
|
commit 0870c7c32cf8a24f234fc066df867747ddb1ddc7
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Tue Nov 13 15:01:43 2012 +0100
|
||||||
|
|
||||||
|
Don't take the address of a variable whose scope is about to disappear.
|
||||||
|
|
||||||
|
commit bb3d7f3b31d4a429d1c31c6621d82f34dd552482
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Sun Nov 11 19:01:28 2012 +0100
|
||||||
|
|
||||||
|
Fix configure script help text for --enable options.
|
||||||
|
|
||||||
|
commit 5bfbb8f6c58307a8109f556caa30be122cc4d39f
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Sun Nov 11 19:01:02 2012 +0100
|
||||||
|
|
||||||
|
Fix index entry for section about readline library.
|
||||||
|
|
||||||
|
commit 5766518589a5e6cc43ba77a4049059ead05fb300
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Sun Nov 11 18:53:23 2012 +0100
|
||||||
|
|
||||||
|
Mention in the manual that support for LZO and zlib can be disabled.
|
||||||
|
|
||||||
|
commit 6ec4596557d658f6c15c2cb9a96152c8c476118a
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Sun Nov 11 18:45:40 2012 +0100
|
||||||
|
|
||||||
|
Mention libcurses and libreadline in the manual.
|
||||||
|
|
||||||
|
commit 0ee139e91431527015b7132e4c36f8d4ec09f66b
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Sat Nov 10 23:45:22 2012 +0100
|
||||||
|
|
||||||
|
Make sure PMTU discovery works in switch mode with VLAN tags.
|
||||||
|
|
||||||
|
Before, when tinc saw a packet larger than the PMTU with a VLAN tag, it would
|
||||||
|
not know what to do with it, and would just forward it via TCP. Now, tinc
|
||||||
|
handles 802.1q packets correctly, as long as there is only one tag.
|
||||||
|
|
||||||
|
commit ade4fccad6857f3d6d548e52bc94ab23751e4fef
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Sat Nov 10 23:13:05 2012 +0100
|
||||||
|
|
||||||
|
Using alloca() for a constant sized buffer is very silly.
|
||||||
|
|
||||||
|
Cppcheck said using alloca() in the 21st century is silly anyway.
|
||||||
|
|
||||||
|
commit b355476e917f377abb6434657933fcf4ffe6870a
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Sat Nov 10 23:09:31 2012 +0100
|
||||||
|
|
||||||
|
Fix potential buffer overflow reading the PID file.
|
||||||
|
|
||||||
|
Found by cppcheck.
|
||||||
|
|
||||||
|
commit edc08b73a9e353bde6db4c73866a6a730a1a7cb4
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Sun Oct 21 17:45:16 2012 +0200
|
||||||
|
|
||||||
|
Slightly randomize all timeouts.
|
||||||
|
|
||||||
|
commit 717ea66d7ba0c23f27d86b3d5c6992b751135455
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Sun Oct 21 17:35:13 2012 +0200
|
||||||
|
|
||||||
|
Add the AutoConnect option.
|
||||||
|
|
||||||
|
When set to a non-zero value, tinc will try to maintain exactly that number of
|
||||||
|
meta connections to other nodes. If there are not enough connections, it will
|
||||||
|
periodically try to set up an outgoing connection to a random node. If there
|
||||||
|
are too many connections, it will periodically try to remove an outgoing
|
||||||
|
connection.
|
||||||
|
|
||||||
|
commit 1f8b70efa0dedbd3642e0ee82a640d125664af34
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Sun Oct 21 17:34:53 2012 +0200
|
||||||
|
|
||||||
|
Keep track of the number of nodes in a tree.
|
||||||
|
|
||||||
|
commit 0006c754f2e61e108aa2dd5a6ddd2e9b50d51bd6
|
||||||
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
Date: Wed Oct 17 13:51:02 2012 +0200
|
||||||
|
|
||||||
|
Fix warnings from groff.
|
||||||
|
|
||||||
commit 0db9e471ea53b48687ea247c855cd95ec453530c
|
commit 0db9e471ea53b48687ea247c855cd95ec453530c
|
||||||
Author: Guus Sliepen <guus@tinc-vpn.org>
|
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||||
Date: Sun Oct 14 19:22:30 2012 +0200
|
Date: Sun Oct 14 19:22:30 2012 +0200
|
||||||
|
|
|
@ -57,10 +57,9 @@ DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
|
||||||
THANKS config.guess config.sub depcomp install-sh missing
|
THANKS config.guess config.sub depcomp install-sh missing
|
||||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||||
am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
|
am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
|
||||||
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libevent.m4 \
|
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/lzo.m4 \
|
||||||
$(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \
|
$(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \
|
||||||
$(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \
|
$(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.in
|
||||||
$(top_srcdir)/configure.in
|
|
||||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||||
$(ACLOCAL_M4)
|
$(ACLOCAL_M4)
|
||||||
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
|
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
|
||||||
|
|
479
NEWS
479
NEWS
|
@ -1,3 +1,17 @@
|
||||||
|
Version 1.1pre4 December 5 2012
|
||||||
|
|
||||||
|
* Added the "AutoConnect" option which will let tinc automatically select
|
||||||
|
which nodes to connect to.
|
||||||
|
|
||||||
|
* Improved performance of VLAN-tagged IP traffic inside the VPN.
|
||||||
|
|
||||||
|
* Ensured LocalDiscovery works with multiple BindToAddress statements and/or
|
||||||
|
IPv6-only LANs.
|
||||||
|
|
||||||
|
* Dropped dependency on libevent.
|
||||||
|
|
||||||
|
* Fixed Windows version not reading packets from the TAP adapter.
|
||||||
|
|
||||||
Version 1.1pre3 October 14 2012
|
Version 1.1pre3 October 14 2012
|
||||||
|
|
||||||
* New experimental protocol:
|
* New experimental protocol:
|
||||||
|
@ -247,7 +261,7 @@ Version 1.0.6 Dec 18 2006
|
||||||
* Fixed a bug where broadcasts in switch and hub modes sometimes would not
|
* Fixed a bug where broadcasts in switch and hub modes sometimes would not
|
||||||
work anymore when part of the VPN had become disconnected from the rest.
|
work anymore when part of the VPN had become disconnected from the rest.
|
||||||
|
|
||||||
version 1.0.5 Nov 14 2006
|
Version 1.0.5 Nov 14 2006
|
||||||
|
|
||||||
* Lots of small fixes.
|
* Lots of small fixes.
|
||||||
|
|
||||||
|
@ -262,347 +276,354 @@ version 1.0.5 Nov 14 2006
|
||||||
|
|
||||||
Thanks to Scott Lamb for his contributions to this version of tinc.
|
Thanks to Scott Lamb for his contributions to this version of tinc.
|
||||||
|
|
||||||
version 1.0.4 May 4 2005
|
Version 1.0.4 May 4 2005
|
||||||
|
|
||||||
* Fix switch and hub modes.
|
* Fix switch and hub modes.
|
||||||
|
|
||||||
* Optionally start scripts when a Subnet becomes (un)reachable.
|
* Optionally start scripts when a Subnet becomes (un)reachable.
|
||||||
|
|
||||||
version 1.0.3 Nov 11 2004
|
Version 1.0.3 Nov 11 2004
|
||||||
|
|
||||||
* Show error message when failing to write a PID file.
|
* Show error message when failing to write a PID file.
|
||||||
|
|
||||||
* Ignore spaces at end of lines in config files.
|
* Ignore spaces at end of lines in config files.
|
||||||
|
|
||||||
* Fix handling of late packets.
|
* Fix handling of late packets.
|
||||||
|
|
||||||
* Unify BSD tun/tap device handling. This allows IPv6 on tun devices and
|
* Unify BSD tun/tap device handling. This allows IPv6 on tun devices and
|
||||||
anything on tap devices as long as the underlying OS supports it.
|
anything on tap devices as long as the underlying OS supports it.
|
||||||
|
|
||||||
* Handle IPv6 on Solaris tun devices.
|
* Handle IPv6 on Solaris tun devices.
|
||||||
|
|
||||||
* Allow tinc to work properly under Windows XP SP2.
|
* Allow tinc to work properly under Windows XP SP2.
|
||||||
|
|
||||||
* Allow VLAN tagged Ethernet frames in switch and hub mode.
|
* Allow VLAN tagged Ethernet frames in switch and hub mode.
|
||||||
|
|
||||||
* Experimental PMTUDiscovery, TunnelServer and BlockingTCP options.
|
* Experimental PMTUDiscovery, TunnelServer and BlockingTCP options.
|
||||||
|
|
||||||
version 1.0.2 Nov 8 2003
|
Version 1.0.2 Nov 8 2003
|
||||||
|
|
||||||
* Fix address and hostname resolving under Windows.
|
* Fix address and hostname resolving under Windows.
|
||||||
|
|
||||||
* Remove warnings about non-existing scripts and unsupported address families.
|
* Remove warnings about non-existing scripts and unsupported address families.
|
||||||
|
|
||||||
* Use the event logger under Windows.
|
* Use the event logger under Windows.
|
||||||
|
|
||||||
* Fix quoting of filenames and command line arguments under Windows.
|
* Fix quoting of filenames and command line arguments under Windows.
|
||||||
|
|
||||||
* Strict checks for length incoming network packets and return values of
|
* Strict checks for length incoming network packets and return values of
|
||||||
cryptographic functions,
|
cryptographic functions,
|
||||||
|
|
||||||
* Fix a bug in metadata handling that made the tinc daemon abort.
|
* Fix a bug in metadata handling that made the tinc daemon abort.
|
||||||
|
|
||||||
version 1.0.1 Aug 14 2003
|
Version 1.0.1 Aug 14 2003
|
||||||
|
|
||||||
* Allow empty lines in config files.
|
* Allow empty lines in config files.
|
||||||
|
|
||||||
* Fix handling of spaces and backslashes in filenames under native Windows.
|
* Fix handling of spaces and backslashes in filenames under native Windows.
|
||||||
|
|
||||||
* Allow scripts to be executed under native Windows.
|
* Allow scripts to be executed under native Windows.
|
||||||
|
|
||||||
* Update documentation, make it less Linux specific.
|
* Update documentation, make it less Linux specific.
|
||||||
|
|
||||||
version 1.0 Aug 4 2003
|
Version 1.0 Aug 4 2003
|
||||||
|
|
||||||
* Lots of small bugfixes and code cleanups.
|
* Lots of small bugfixes and code cleanups.
|
||||||
|
|
||||||
* Throughput doubled and latency reduced.
|
* Throughput doubled and latency reduced.
|
||||||
|
|
||||||
* Added support for LZO compression.
|
* Added support for LZO compression.
|
||||||
|
|
||||||
* No need to set MAC address or disable ARP anymore.
|
* No need to set MAC address or disable ARP anymore.
|
||||||
|
|
||||||
* Added support for Windows 2000 and XP, both natively and in a Cygwin
|
* Added support for Windows 2000 and XP, both natively and in a Cygwin
|
||||||
environment.
|
environment.
|
||||||
|
|
||||||
version 1.0pre8 Sep 16 2002
|
Version 1.0pre8 Sep 16 2002
|
||||||
|
|
||||||
* More fixes for subnets with prefixlength undivisible by 8.
|
* More fixes for subnets with prefixlength undivisible by 8.
|
||||||
|
|
||||||
* Added support for NetBSD and MacOS/X.
|
* Added support for NetBSD and MacOS/X.
|
||||||
|
|
||||||
* Switched from undirected graphs to directed graphs to avoid certain race
|
* Switched from undirected graphs to directed graphs to avoid certain race
|
||||||
conditions and improve scalability.
|
conditions and improve scalability.
|
||||||
|
|
||||||
* Generalized broadcasting and forwarding of protocol messages.
|
* Generalized broadcasting and forwarding of protocol messages.
|
||||||
|
|
||||||
* Cleanup of source code.
|
* Cleanup of source code.
|
||||||
|
|
||||||
|
Version 1.0pre7 Apr 7 2002
|
||||||
|
|
||||||
version 1.0pre7 Apr 7 2002
|
* Don't do blocking read()s when getting a signal.
|
||||||
|
|
||||||
* Don't do blocking read()s when getting a signal.
|
* Remove RSA key checking code, since it sometimes thinks perfectly good RSA
|
||||||
|
keys are bad.
|
||||||
|
|
||||||
* Remove RSA key checking code, since it sometimes thinks perfectly good RSA
|
* Fix handling of subnets when prefixlength isn't divisible by 8.
|
||||||
keys are bad.
|
|
||||||
|
|
||||||
* Fix handling of subnets when prefixlength isn't divisible by 8.
|
Version 1.0pre6 Mar 27 2002
|
||||||
|
|
||||||
|
* Improvement of redundant links:
|
||||||
|
* Non-blocking connects.
|
||||||
|
* Protocol broadcast messages can no longer go into an infinite loop.
|
||||||
|
* Graph algorithm updated to look harder for direct connections.
|
||||||
|
|
||||||
version 1.0pre6 Mar 27 2002
|
* Good support for routing IPv6 packets over the VPN. Works on Linux,
|
||||||
|
FreeBSD, possibly OpenBSD but not on Solaris.
|
||||||
|
|
||||||
* Improvement of redundant links:
|
* Support for tunnels over IPv6 networks. Works on all supported
|
||||||
|
operating systems.
|
||||||
|
|
||||||
* Non-blocking connects.
|
* Optional compression of UDP connections using zlib.
|
||||||
|
|
||||||
* Protocol broadcast messages can no longer go into an infinite loop.
|
* Optionally let UDP connections inherit TOS field of tunneled packets.
|
||||||
|
|
||||||
* Graph algorithm updated to look harder for direct connections.
|
* Optionally start scripts when certain hosts become (un)reachable.
|
||||||
|
|
||||||
* Good support for routing IPv6 packets over the VPN. Works on Linux,
|
Version 1.0pre5 Feb 9 2002
|
||||||
FreeBSD, possibly OpenBSD but not on Solaris.
|
|
||||||
|
|
||||||
* Support for tunnels over IPv6 networks. Works on all supported
|
* Security enhancements:
|
||||||
operating systems.
|
* Added sequence number and optional message authentication code to
|
||||||
|
the packets.
|
||||||
|
* Configurable encryption cipher and digest algorithms.
|
||||||
|
|
||||||
* Optional compression of UDP connections using zlib.
|
* More robust handling of dis- and reconnects.
|
||||||
|
|
||||||
* Optionally let UDP connections inherit TOS field of tunneled packets.
|
* Added a "switch" and a "hub" mode to allow bridging setups.
|
||||||
|
|
||||||
* Optionally start scripts when certain hosts become (un)reachable.
|
* Preliminary support for routing of IPv6 packets.
|
||||||
|
|
||||||
|
* Supports Linux, FreeBSD, OpenBSD and Solaris.
|
||||||
|
|
||||||
version 1.0pre5 Feb 9 2002
|
Version 1.0pre4 Jan 17 2001
|
||||||
|
|
||||||
* Security enhancements:
|
* Updated documentation; the documentation now reflects the
|
||||||
|
configuration as it is.
|
||||||
|
|
||||||
* Added sequence number and optional message authentication code to
|
* Some internal changes to make tinc scale better for large
|
||||||
the packets.
|
networks, such as using AVL trees instead of linked lists for the
|
||||||
|
connection list.
|
||||||
|
|
||||||
* Configurable encryption cipher and digest algorithms.
|
* RSA keys can be stored in separate files if needed. See the
|
||||||
|
documentation for more information.
|
||||||
|
|
||||||
* More robust handling of dis- and reconnects.
|
* Tinc has now been reported to run on Linux PowerPC and FreeBSD x86.
|
||||||
|
|
||||||
* Added a "switch" and a "hub" mode to allow bridging setups.
|
Version 1.0pre3 Oct 31 2000
|
||||||
|
|
||||||
* Preliminary support for routing of IPv6 packets.
|
* The protocol has been redesigned, and although some details are
|
||||||
|
still under discussion, this is secure. Care has been taken to
|
||||||
|
resist most, if not all, attacks.
|
||||||
|
|
||||||
* Supports Linux, FreeBSD, OpenBSD and Solaris.
|
* Unfortunately this protocol is not compatible with earlier versions,
|
||||||
|
nor are earlier versions compatible with this version. Because the
|
||||||
|
older protocol has huge security flaws, we feel that not
|
||||||
|
implementing backwards compatibility is justified.
|
||||||
|
|
||||||
|
* Some data about the protocol:
|
||||||
|
* It uses public/private RSA keys for authentication (this is the
|
||||||
|
actual fix for the security hole).
|
||||||
|
* All cryptographic functions have been taken out of tinc, instead
|
||||||
|
it uses the OpenSSL library functions.
|
||||||
|
* Offers support for multiple subnets per tinc daemon.
|
||||||
|
|
||||||
It looks like this might be the last release before 1.0.
|
* New is also the support for the universal tun/tap device. This
|
||||||
|
means better portability to FreeBSD and Solaris.
|
||||||
|
|
||||||
|
* Tinc is tested to compile on Solaris, Linux x86, Linux alpha.
|
||||||
|
|
||||||
version 1.0pre4 Jan 17 2001
|
* Tinc now uses the OpenSSL library for cryptographic operations.
|
||||||
|
More information on getting and installing OpenSSL is in the manual.
|
||||||
|
This also means that the GMP library is no longer required.
|
||||||
|
|
||||||
* Updated documentation; the documentation now reflects the
|
* Further, thanks to Enrique Zanardi, we have Spanish messages; Matias
|
||||||
configuration as it is.
|
Carrasco provided us with a Spanish translation of the manual.
|
||||||
|
|
||||||
* Some internal changes to make tinc scale better for large
|
Version 1.0pre2 May 31 2000
|
||||||
networks, such as using AVL trees instead of linked lists for the
|
|
||||||
connection list.
|
|
||||||
|
|
||||||
* RSA keys can be stored in separate files if needed. See the
|
* This version has been internationalized; and a Dutch translation has
|
||||||
documentation for more information.
|
been included.
|
||||||
|
|
||||||
* tinc has now been reported to run on Linux PowerPC and FreeBSD x86.
|
* Two configuration variables have been added:
|
||||||
|
* VpnMask - the IP network mask for the entire VPN, not just our
|
||||||
|
subnet (as given by MyVirtualIP). The Redhat and Debian packages
|
||||||
|
use this variable in their system startup scripts, but it is
|
||||||
|
ignored by tinc.
|
||||||
|
* Hostnames - if set to `yes', look up the names of IP addresses
|
||||||
|
trying to connect to us. Default set to `no', to prevent lockups
|
||||||
|
during lookups.
|
||||||
|
|
||||||
|
* The system startup scripts for Debian and Redhat use
|
||||||
|
/etc/tinc/nets.boot to find out which networks need to be started
|
||||||
|
during system boot.
|
||||||
|
|
||||||
|
* Fixes to prevent denial of service attacks by sending random data
|
||||||
|
after connecting (and even when the connection has been established),
|
||||||
|
either random garbage or just nonsensical protocol fields.
|
||||||
|
|
||||||
version 1.0pre3 Oct 31 2000
|
* Tinc will retry to connect upon startup, does not quit if it doesn't
|
||||||
|
work the first time.
|
||||||
|
|
||||||
* The protocol has been redesigned, and although some details are
|
* Hosts that are disconnected implicitly if we lose a connection get
|
||||||
still under discussion, this is secure. Care has been taken to
|
deleted from the internal list, to prevent hogging eachother with
|
||||||
resist most, if not all, attacks.
|
add and delete requests when the connection is restored.
|
||||||
|
|
||||||
* Unfortunately this protocol is not compatible with earlier versions,
|
Version 1.0pre1 May 12 2000
|
||||||
nor are earlier versions compatible with this version. Because the
|
|
||||||
older protocol has huge security flaws, we feel that not
|
|
||||||
implementing backwards compatibility is justified.
|
|
||||||
|
|
||||||
* Some data about the protocol:
|
|
||||||
|
|
||||||
* It uses public/private RSA keys for authentication (this is the
|
|
||||||
actual fix for the security hole).
|
|
||||||
|
|
||||||
* All cryptographic functions have been taken out of tinc, instead
|
|
||||||
it uses the OpenSSL library functions.
|
|
||||||
|
|
||||||
* Offers support for multiple subnets per tinc daemon.
|
|
||||||
|
|
||||||
* New is also the support for the universal tun/tap device. This
|
|
||||||
means better portability to FreeBSD and Solaris.
|
|
||||||
|
|
||||||
* tinc is tested to compile on Solaris, Linux x86, Linux alpha.
|
|
||||||
|
|
||||||
* tinc now uses the OpenSSL library for cryptographic operations.
|
|
||||||
More information on getting and installing OpenSSL is in the manual.
|
|
||||||
This also means that the GMP library is no longer required.
|
|
||||||
|
|
||||||
* Further, thanks to Enrique Zanardi, we have Spanish messages; Matias
|
|
||||||
Carrasco provided us with a Spanish translation of the manual.
|
|
||||||
|
|
||||||
|
|
||||||
What still needs to be done before 1.0:
|
|
||||||
|
|
||||||
* Documentation. Especially since the protocol has changed, and a lot
|
|
||||||
of configuration directives have been added.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
version 1.0pre2 May 31 2000
|
|
||||||
|
|
||||||
* This version has been internationalized; and a Dutch translation has
|
|
||||||
been included.
|
|
||||||
|
|
||||||
* Two configuration variables have been added:
|
|
||||||
* VpnMask - the IP network mask for the entire VPN, not just our
|
|
||||||
subnet (as given by MyVirtualIP). The Redhat and Debian packages
|
|
||||||
use this variable in their system startup scripts, but it is
|
|
||||||
ignored by tinc.
|
|
||||||
* Hostnames - if set to `yes', look up the names of IP addresses
|
|
||||||
trying to connect to us. Default set to `no', to prevent lockups
|
|
||||||
during lookups.
|
|
||||||
|
|
||||||
* The system startup scripts for Debian and Redhat use
|
|
||||||
/etc/tinc/nets.boot to find out which networks need to be started
|
|
||||||
during system boot.
|
|
||||||
|
|
||||||
* Fixes to prevent denial of service attacks by sending random data
|
|
||||||
after connecting (and even when the connection has been established),
|
|
||||||
either random garbage or just nonsensical protocol fields.
|
|
||||||
|
|
||||||
* tinc will retry to connect upon startup, does not quit if it doesn't
|
|
||||||
work the first time.
|
|
||||||
|
|
||||||
* Hosts that are disconnected implicitly if we lose a connection get
|
|
||||||
deleted from the internal list, to prevent hogging eachother with
|
|
||||||
add and delete requests when the connection is restored.
|
|
||||||
|
|
||||||
|
|
||||||
What still needs to be done before 1.0:
|
|
||||||
|
|
||||||
* Documentation.
|
|
||||||
* Failover ConnectTo lines, try another one if the first doesn't work.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
version 1.0pre1 May 12 2000
|
|
||||||
* New meta-protocol
|
* New meta-protocol
|
||||||
|
|
||||||
* Various other bugfixes
|
* Various other bugfixes
|
||||||
|
|
||||||
* Documentation updates
|
* Documentation updates
|
||||||
|
|
||||||
version 0.3.3 Feb 9 2000
|
Version 0.3.3 Feb 9 2000
|
||||||
* Fixed bug that made tinc stop working with latest kernels (Guus
|
|
||||||
Sliepen)
|
* Fixed bug that made tinc stop working with latest kernels
|
||||||
|
|
||||||
* Updated the manual
|
* Updated the manual
|
||||||
|
|
||||||
version 0.3.2 Nov 12 1999
|
Version 0.3.2 Nov 12 1999
|
||||||
* no more `Invalid filedescriptor' when working with multiple
|
|
||||||
connections
|
|
||||||
* forward unknown packets to uplink
|
|
||||||
|
|
||||||
version 0.3.1 Oct 20 1999
|
* No more `Invalid filedescriptor' when working with multiple
|
||||||
* fixed a bug where tinc would exit without a trace
|
connections.
|
||||||
|
|
||||||
version 0.3 Aug 20 1999
|
* Forward unknown packets to uplink.
|
||||||
* pings now work immediately
|
|
||||||
* all packet sizes get transmitted correctly
|
|
||||||
|
|
||||||
version 0.2.26 Aug 15 1999
|
Version 0.3.1 Oct 20 1999
|
||||||
* fixed some remaining bugs
|
|
||||||
* --sysconfdir works with configure
|
|
||||||
* last version before 0.3
|
|
||||||
|
|
||||||
version 0.2.25 Aug 8 1999
|
* Fixed a bug where tinc would exit without a trace.
|
||||||
* improved stability, going towards 0.3 now.
|
|
||||||
|
|
||||||
version 0.2.24 Aug 7 1999
|
Version 0.3 Aug 20 1999
|
||||||
* added key aging, there's a new config variable, KeyExpire.
|
|
||||||
* updated man and info pages
|
|
||||||
|
|
||||||
version 0.2.23 Aug 5 1999
|
* Pings now work immediately.
|
||||||
* all known bugs fixed, this is a candidate for 0.3
|
|
||||||
|
|
||||||
version 0.2.22 Apr 11 1999
|
* All packet sizes get transmitted correctly.
|
||||||
* multiconnection thing is now working nearly perfect :)
|
|
||||||
|
Version 0.2.26 Aug 15 1999
|
||||||
|
|
||||||
|
* Fixed some remaining bugs.
|
||||||
|
|
||||||
|
* --sysconfdir works with configure.
|
||||||
|
|
||||||
|
* Last version before 0.3.
|
||||||
|
|
||||||
|
Version 0.2.25 Aug 8 1999
|
||||||
|
|
||||||
|
* Improved stability, going towards 0.3 now.
|
||||||
|
|
||||||
|
Version 0.2.24 Aug 7 1999
|
||||||
|
|
||||||
|
* Added key aging, there's a new config variable, KeyExpire.
|
||||||
|
|
||||||
|
* Updated man and info pages.
|
||||||
|
|
||||||
|
Version 0.2.23 Aug 5 1999
|
||||||
|
|
||||||
|
* All known bugs fixed, this is a candidate for 0.3.
|
||||||
|
|
||||||
|
Version 0.2.22 Apr 11 1999
|
||||||
|
|
||||||
|
* Multiconnection thing is now working nearly perfect :)
|
||||||
|
|
||||||
|
Version 0.2.21 Apr 10 1999
|
||||||
|
|
||||||
version 0.2.21 Apr 10 1999
|
|
||||||
* You shouldn't notice a thing, but a lot has changed wrt key
|
* You shouldn't notice a thing, but a lot has changed wrt key
|
||||||
management - except that it refuses to talk to versions < 0.2.20
|
management - except that it refuses to talk to versions < 0.2.20
|
||||||
|
|
||||||
version 0.2.20
|
Version 0.2.19 Apr 3 1999
|
||||||
|
|
||||||
version 0.2.19 Apr 3 1999
|
* Don't install a libcipher.so.
|
||||||
* don't install a libcipher.so
|
|
||||||
|
|
||||||
version 0.2.18 Apr 3 1999
|
Version 0.2.18 Apr 3 1999
|
||||||
* blowfish library dynamically loaded upon execution
|
|
||||||
* included Eric Young's IDEA library
|
|
||||||
|
|
||||||
version 0.2.17 Apr 1 1999
|
* Blowfish library dynamically loaded upon execution.
|
||||||
* tincd now re-executes itself in case of a segmentation fault.
|
|
||||||
|
|
||||||
version 0.2.16 Apr 1 1999
|
* Included Eric Young's IDEA library.
|
||||||
* wrote tincd.conf(5) man page, which still needs a lot of work.
|
|
||||||
* config file now accepts and tolerates spaces, and any integer base
|
|
||||||
for integer variables, and better error reporting. See
|
|
||||||
doc/tincd.conf.sample for an example.
|
|
||||||
|
|
||||||
version 0.2.15 Mar 29 1999
|
Version 0.2.17 Apr 1 1999
|
||||||
* fixed bugs
|
|
||||||
|
|
||||||
version 0.2.14 Feb 10 1999
|
* Tincd now re-executes itself in case of a segmentation fault.
|
||||||
* added --timeout flag and PingTimeout configuration
|
|
||||||
* did some first syslog cleanup work
|
|
||||||
|
|
||||||
version 0.2.13 Jan 23 1999
|
Version 0.2.16 Apr 1 1999
|
||||||
* bugfixes
|
|
||||||
|
|
||||||
version 0.2.12 Jan 23 1999
|
* Wrote tincd.conf(5) man page, which still needs a lot of work.
|
||||||
* fixed nauseating bug so that it would crash whenever a connection
|
|
||||||
got lost
|
|
||||||
|
|
||||||
version 0.2.11 Jan 22 1999
|
* Config file now accepts and tolerates spaces, and any integer base
|
||||||
* framework for multiple connections has been done
|
for integer variables, and better error reporting. See
|
||||||
* simple manpage for tincd
|
doc/tincd.conf.sample for an example.
|
||||||
|
|
||||||
version 0.2.10 Jan 18 1999
|
Version 0.2.15 Mar 29 1999
|
||||||
* passphrase support added
|
|
||||||
|
|
||||||
version 0.2.9 Jan 13 1999
|
* Fixed bugs.
|
||||||
* bugs fixed.
|
|
||||||
|
|
||||||
version 0.2.8 Jan 11 1999
|
Version 0.2.14 Feb 10 1999
|
||||||
* a reworked protocol version
|
|
||||||
* a ping/pong system
|
|
||||||
* more reliable networking code
|
|
||||||
* automatic reconnection
|
|
||||||
* still does not work with more than one connection :)
|
|
||||||
* strips MAC addresses before sending, so there's less overhead, and
|
|
||||||
less redundancy
|
|
||||||
|
|
||||||
version 0.2.7 Jan 3 1999
|
* Added --timeout flag and PingTimeout configuration.
|
||||||
* several updates to make extending more easy.
|
* Did some first syslog cleanup work.
|
||||||
|
|
||||||
|
Version 0.2.13 Jan 23 1999
|
||||||
|
|
||||||
|
* Bugfixes.
|
||||||
|
|
||||||
|
Version 0.2.12 Jan 23 1999
|
||||||
|
|
||||||
|
* Fixed nauseating bug so that it would crash whenever a connection
|
||||||
|
got lost.
|
||||||
|
|
||||||
|
Version 0.2.11 Jan 22 1999
|
||||||
|
|
||||||
|
* Framework for multiple connections has been done.
|
||||||
|
|
||||||
|
* Simple manpage for tincd.
|
||||||
|
|
||||||
|
Version 0.2.10 Jan 18 1999
|
||||||
|
|
||||||
|
* Passphrase support added.
|
||||||
|
|
||||||
|
Version 0.2.9 Jan 13 1999
|
||||||
|
|
||||||
|
* Bugs fixed.
|
||||||
|
|
||||||
|
Version 0.2.8 Jan 11 1999
|
||||||
|
|
||||||
|
* A reworked protocol version.
|
||||||
|
|
||||||
|
* A ping/pong system.
|
||||||
|
|
||||||
|
* More reliable networking code.
|
||||||
|
|
||||||
|
* Automatic reconnection.
|
||||||
|
|
||||||
|
* Still does not work with more than one connection :)
|
||||||
|
|
||||||
|
* Strips MAC addresses before sending, so there's less overhead, and
|
||||||
|
less redundancy.
|
||||||
|
|
||||||
|
Version 0.2.7 Jan 3 1999
|
||||||
|
|
||||||
|
* Several updates to make extending more easy.
|
||||||
|
|
||||||
|
Version 0.2.6 Dec 20 1998
|
||||||
|
|
||||||
version 0.2.6 Dec 20 1998
|
|
||||||
* Point-to-Point connections have been established, including
|
* Point-to-Point connections have been established, including
|
||||||
blowfish encryption and a secret key-exchange.
|
Blowfish encryption and a secret key-exchange.
|
||||||
|
|
||||||
|
Version 0.2.5 Dec 16 1998
|
||||||
|
|
||||||
version 0.2.5 Dec 16 1998
|
|
||||||
* Project renamed to tinc, in honour of TINC.
|
* Project renamed to tinc, in honour of TINC.
|
||||||
|
|
||||||
version 0.2.4 Dec 16 1998
|
Version 0.2.4 Dec 16 1998
|
||||||
* now it really does ;)
|
|
||||||
|
|
||||||
version 0.2.3 Nov 24 1998
|
* Now it really does ;)
|
||||||
* it sort of works now
|
|
||||||
|
|
||||||
version 0.2.2 Nov 20 1998
|
Version 0.2.3 Nov 24 1998
|
||||||
* uses GNU gmp.
|
|
||||||
|
|
||||||
version 0.2.1 Nov 14 1998
|
* It sort of works now.
|
||||||
|
|
||||||
|
Version 0.2.2 Nov 20 1998
|
||||||
|
|
||||||
|
* Uses GNU gmp.
|
||||||
|
|
||||||
|
Version 0.2.1 Nov 14 1998
|
||||||
|
|
||||||
* Bare version.
|
* Bare version.
|
||||||
|
|
7
README
7
README
|
@ -1,4 +1,4 @@
|
||||||
This is the README file for tinc version 1.1pre3. Installation
|
This is the README file for tinc version 1.1pre4. Installation
|
||||||
instructions may be found in the INSTALL file.
|
instructions may be found in the INSTALL file.
|
||||||
|
|
||||||
tinc is Copyright (C) 1998-2012 by:
|
tinc is Copyright (C) 1998-2012 by:
|
||||||
|
@ -36,11 +36,11 @@ at your own risk.
|
||||||
Compatibility
|
Compatibility
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
Version 1.1pre3 is compatible with 1.0pre8, 1.0 and later, but not with older
|
Version 1.1pre4 is compatible with 1.0pre8, 1.0 and later, but not with older
|
||||||
versions of tinc.
|
versions of tinc.
|
||||||
|
|
||||||
When the ExperimentalProtocol option is used, tinc is still compatible with
|
When the ExperimentalProtocol option is used, tinc is still compatible with
|
||||||
1.0.X and 1.1pre3 itself, but not with any other 1.1preX version.
|
1.0.X and 1.1pre4 itself, but not with any other 1.1preX version.
|
||||||
|
|
||||||
|
|
||||||
Requirements
|
Requirements
|
||||||
|
@ -50,7 +50,6 @@ In order to compile tinc, you will need a GNU C compiler environment. Please
|
||||||
ensure you have the latest stable versions of all the required libraries:
|
ensure you have the latest stable versions of all the required libraries:
|
||||||
|
|
||||||
- OpenSSL (http://www.openssl.org/) version 1.0.0 or later.
|
- OpenSSL (http://www.openssl.org/) version 1.0.0 or later.
|
||||||
- Libevent (http://monkey.org/~provos/libevent/)
|
|
||||||
|
|
||||||
The following libraries are used by default, but can be disabled if necessary:
|
The following libraries are used by default, but can be disabled if necessary:
|
||||||
|
|
||||||
|
|
1
aclocal.m4
vendored
1
aclocal.m4
vendored
|
@ -1135,7 +1135,6 @@ AC_SUBST([am__untar])
|
||||||
|
|
||||||
m4_include([m4/attribute.m4])
|
m4_include([m4/attribute.m4])
|
||||||
m4_include([m4/curses.m4])
|
m4_include([m4/curses.m4])
|
||||||
m4_include([m4/libevent.m4])
|
|
||||||
m4_include([m4/lzo.m4])
|
m4_include([m4/lzo.m4])
|
||||||
m4_include([m4/openssl.m4])
|
m4_include([m4/openssl.m4])
|
||||||
m4_include([m4/readline.m4])
|
m4_include([m4/readline.m4])
|
||||||
|
|
|
@ -64,9 +64,6 @@
|
||||||
/* Define to 1 if you have the `ECDSA_verify' function. */
|
/* Define to 1 if you have the `ECDSA_verify' function. */
|
||||||
#undef HAVE_ECDSA_VERIFY
|
#undef HAVE_ECDSA_VERIFY
|
||||||
|
|
||||||
/* Define to 1 if you have the <event.h> header file. */
|
|
||||||
#undef HAVE_EVENT_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `EVP_EncryptInit_ex' function. */
|
/* Define to 1 if you have the `EVP_EncryptInit_ex' function. */
|
||||||
#undef HAVE_EVP_ENCRYPTINIT_EX
|
#undef HAVE_EVP_ENCRYPTINIT_EX
|
||||||
|
|
||||||
|
|
112
configure
vendored
112
configure
vendored
|
@ -738,7 +738,6 @@ enable_uml
|
||||||
enable_vde
|
enable_vde
|
||||||
enable_tunemu
|
enable_tunemu
|
||||||
with_windows2000
|
with_windows2000
|
||||||
with_libgcrypt
|
|
||||||
enable_curses
|
enable_curses
|
||||||
with_curses
|
with_curses
|
||||||
with_curses_include
|
with_curses_include
|
||||||
|
@ -747,9 +746,6 @@ enable_readline
|
||||||
with_readline
|
with_readline
|
||||||
with_readline_include
|
with_readline_include
|
||||||
with_readline_lib
|
with_readline_lib
|
||||||
with_libevent
|
|
||||||
with_libevent_include
|
|
||||||
with_libevent_lib
|
|
||||||
enable_zlib
|
enable_zlib
|
||||||
with_zlib
|
with_zlib
|
||||||
with_zlib_include
|
with_zlib_include
|
||||||
|
@ -1393,9 +1389,9 @@ Optional Features:
|
||||||
--enable-dependency-tracking do not reject slow dependency extractors
|
--enable-dependency-tracking do not reject slow dependency extractors
|
||||||
--enable-maintainer-mode enable make rules and dependencies not useful
|
--enable-maintainer-mode enable make rules and dependencies not useful
|
||||||
(and sometimes confusing) to the casual installer
|
(and sometimes confusing) to the casual installer
|
||||||
--disable-uml enable support for User Mode Linux
|
--enable-uml enable support for User Mode Linux
|
||||||
--disable-vde enable support for Virtual Distributed Ethernet
|
--enable-vde enable support for Virtual Distributed Ethernet
|
||||||
--disable-tunemu enable support for the tunemu driver
|
--enable-tunemu enable support for the tunemu driver
|
||||||
--disable-curses disable curses support
|
--disable-curses disable curses support
|
||||||
--disable-readline disable readline support
|
--disable-readline disable readline support
|
||||||
--disable-zlib disable zlib compression support
|
--disable-zlib disable zlib compression support
|
||||||
|
@ -1408,7 +1404,6 @@ Optional Packages:
|
||||||
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
|
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
|
||||||
--without-windows2000 compile with support for Windows 2000. This disables
|
--without-windows2000 compile with support for Windows 2000. This disables
|
||||||
support for tunneling over existing IPv6 networks.
|
support for tunneling over existing IPv6 networks.
|
||||||
--with-libgcrypt enable use of libgcrypt instead of OpenSSL]
|
|
||||||
--with-curses=DIR curses base directory, or:
|
--with-curses=DIR curses base directory, or:
|
||||||
--with-curses-include=DIR
|
--with-curses-include=DIR
|
||||||
curses headers directory
|
curses headers directory
|
||||||
|
@ -1417,10 +1412,6 @@ Optional Packages:
|
||||||
--with-readline-include=DIR
|
--with-readline-include=DIR
|
||||||
readline headers directory
|
readline headers directory
|
||||||
--with-readline-lib=DIR readline library directory
|
--with-readline-lib=DIR readline library directory
|
||||||
--with-libevent=DIR libevent base directory, or:
|
|
||||||
--with-libevent-include=DIR
|
|
||||||
libevent headers directory
|
|
||||||
--with-libevent-lib=DIR libevent library directory
|
|
||||||
--with-zlib=DIR zlib base directory, or:
|
--with-zlib=DIR zlib base directory, or:
|
||||||
--with-zlib-include=DIR zlib headers directory
|
--with-zlib-include=DIR zlib headers directory
|
||||||
--with-zlib-lib=DIR zlib library directory
|
--with-zlib-lib=DIR zlib library directory
|
||||||
|
@ -4104,7 +4095,7 @@ fi
|
||||||
|
|
||||||
# Define the identity of the package.
|
# Define the identity of the package.
|
||||||
PACKAGE=tinc
|
PACKAGE=tinc
|
||||||
VERSION=1.1pre3
|
VERSION=1.1pre4
|
||||||
|
|
||||||
|
|
||||||
cat >>confdefs.h <<_ACEOF
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
@ -5929,12 +5920,6 @@ rm -f confcache
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Check whether --with-libgcrypt was given.
|
|
||||||
if test "${with_libgcrypt+set}" = set; then :
|
|
||||||
withval=$with_libgcrypt;
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Check whether --enable-curses was given.
|
# Check whether --enable-curses was given.
|
||||||
if test "${enable_curses+set}" = set; then :
|
if test "${enable_curses+set}" = set; then :
|
||||||
|
@ -6145,95 +6130,6 @@ fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Check whether --with-libevent was given.
|
|
||||||
if test "${with_libevent+set}" = set; then :
|
|
||||||
withval=$with_libevent; libevent="$withval"
|
|
||||||
CPPFLAGS="$CPPFLAGS -I$withval/include"
|
|
||||||
LDFLAGS="$LDFLAGS -L$withval/lib"
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Check whether --with-libevent-include was given.
|
|
||||||
if test "${with_libevent_include+set}" = set; then :
|
|
||||||
withval=$with_libevent_include; libevent_include="$withval"
|
|
||||||
CPPFLAGS="$CPPFLAGS -I$withval"
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Check whether --with-libevent-lib was given.
|
|
||||||
if test "${with_libevent_lib+set}" = set; then :
|
|
||||||
withval=$with_libevent_lib; libevent_lib="$withval"
|
|
||||||
LDFLAGS="$LDFLAGS -L$withval"
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
for ac_header in event.h
|
|
||||||
do :
|
|
||||||
ac_fn_c_check_header_mongrel "$LINENO" "event.h" "ac_cv_header_event_h" "$ac_includes_default"
|
|
||||||
if test "x$ac_cv_header_event_h" = xyes; then :
|
|
||||||
cat >>confdefs.h <<_ACEOF
|
|
||||||
#define HAVE_EVENT_H 1
|
|
||||||
_ACEOF
|
|
||||||
|
|
||||||
else
|
|
||||||
as_fn_error $? "\"libevent header files not found.\"" "$LINENO" 5; break
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
done
|
|
||||||
|
|
||||||
|
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for event_init in -levent" >&5
|
|
||||||
$as_echo_n "checking for event_init in -levent... " >&6; }
|
|
||||||
if ${ac_cv_lib_event_event_init+:} false; then :
|
|
||||||
$as_echo_n "(cached) " >&6
|
|
||||||
else
|
|
||||||
ac_check_lib_save_LIBS=$LIBS
|
|
||||||
LIBS="-levent $LIBS"
|
|
||||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
|
||||||
/* end confdefs.h. */
|
|
||||||
|
|
||||||
/* Override any GCC internal prototype to avoid an error.
|
|
||||||
Use char because int might match the return type of a GCC
|
|
||||||
builtin and then its argument prototype would still apply. */
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
#endif
|
|
||||||
char event_init ();
|
|
||||||
int
|
|
||||||
main ()
|
|
||||||
{
|
|
||||||
return event_init ();
|
|
||||||
;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
_ACEOF
|
|
||||||
if ac_fn_c_try_link "$LINENO"; then :
|
|
||||||
ac_cv_lib_event_event_init=yes
|
|
||||||
else
|
|
||||||
ac_cv_lib_event_event_init=no
|
|
||||||
fi
|
|
||||||
rm -f core conftest.err conftest.$ac_objext \
|
|
||||||
conftest$ac_exeext conftest.$ac_ext
|
|
||||||
LIBS=$ac_check_lib_save_LIBS
|
|
||||||
fi
|
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_event_event_init" >&5
|
|
||||||
$as_echo "$ac_cv_lib_event_event_init" >&6; }
|
|
||||||
if test "x$ac_cv_lib_event_event_init" = xyes; then :
|
|
||||||
LIBS="-levent $LIBS"
|
|
||||||
else
|
|
||||||
as_fn_error $? "\"libevent libraries not found.\"" "$LINENO" 5
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Check whether --enable-zlib was given.
|
# Check whether --enable-zlib was given.
|
||||||
if test "${enable_zlib+set}" = set; then :
|
if test "${enable_zlib+set}" = set; then :
|
||||||
enableval=$enable_zlib;
|
enableval=$enable_zlib;
|
||||||
|
|
11
configure.in
11
configure.in
|
@ -4,7 +4,7 @@ AC_PREREQ(2.61)
|
||||||
AC_INIT
|
AC_INIT
|
||||||
AC_CONFIG_SRCDIR([src/tincd.c])
|
AC_CONFIG_SRCDIR([src/tincd.c])
|
||||||
AC_GNU_SOURCE
|
AC_GNU_SOURCE
|
||||||
AM_INIT_AUTOMAKE(tinc, 1.1pre3)
|
AM_INIT_AUTOMAKE(tinc, 1.1pre4)
|
||||||
AC_CONFIG_HEADERS([config.h])
|
AC_CONFIG_HEADERS([config.h])
|
||||||
AM_MAINTAINER_MODE
|
AM_MAINTAINER_MODE
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ case $host_os in
|
||||||
esac
|
esac
|
||||||
|
|
||||||
AC_ARG_ENABLE(uml,
|
AC_ARG_ENABLE(uml,
|
||||||
AS_HELP_STRING([--disable-uml], [enable support for User Mode Linux]),
|
AS_HELP_STRING([--enable-uml], [enable support for User Mode Linux]),
|
||||||
[ AS_IF([test "x$enable_uml" = "xyes"],
|
[ AS_IF([test "x$enable_uml" = "xyes"],
|
||||||
[ AC_DEFINE(ENABLE_UML, 1, [Support for UML])
|
[ AC_DEFINE(ENABLE_UML, 1, [Support for UML])
|
||||||
uml=true
|
uml=true
|
||||||
|
@ -85,7 +85,7 @@ AC_ARG_ENABLE(uml,
|
||||||
)
|
)
|
||||||
|
|
||||||
AC_ARG_ENABLE(vde,
|
AC_ARG_ENABLE(vde,
|
||||||
AS_HELP_STRING([--disable-vde], [enable support for Virtual Distributed Ethernet]),
|
AS_HELP_STRING([--enable-vde], [enable support for Virtual Distributed Ethernet]),
|
||||||
[ AS_IF([test "x$enable_vde" = "xyes"],
|
[ AS_IF([test "x$enable_vde" = "xyes"],
|
||||||
[ AC_CHECK_HEADERS(libvdeplug_dyn.h, [], [AC_MSG_ERROR([VDE plug header files not found.]); break])
|
[ AC_CHECK_HEADERS(libvdeplug_dyn.h, [], [AC_MSG_ERROR([VDE plug header files not found.]); break])
|
||||||
AC_DEFINE(ENABLE_VDE, 1, [Support for VDE])
|
AC_DEFINE(ENABLE_VDE, 1, [Support for VDE])
|
||||||
|
@ -97,7 +97,7 @@ AC_ARG_ENABLE(vde,
|
||||||
)
|
)
|
||||||
|
|
||||||
AC_ARG_ENABLE(tunemu,
|
AC_ARG_ENABLE(tunemu,
|
||||||
AS_HELP_STRING([--disable-tunemu], [enable support for the tunemu driver]),
|
AS_HELP_STRING([--enable-tunemu], [enable support for the tunemu driver]),
|
||||||
[ AS_IF([test "x$enable_tunemu" = "xyes"],
|
[ AS_IF([test "x$enable_tunemu" = "xyes"],
|
||||||
[ AC_DEFINE(ENABLE_TUNEMU, 1, [Support for tunemu])
|
[ AC_DEFINE(ENABLE_TUNEMU, 1, [Support for tunemu])
|
||||||
tunemu=true
|
tunemu=true
|
||||||
|
@ -179,11 +179,10 @@ AC_CACHE_SAVE
|
||||||
|
|
||||||
dnl These are defined in files in m4/
|
dnl These are defined in files in m4/
|
||||||
|
|
||||||
AC_ARG_WITH(libgcrypt, AC_HELP_STRING([--with-libgcrypt], [enable use of libgcrypt instead of OpenSSL])], [])
|
dnl AC_ARG_WITH(libgcrypt, AC_HELP_STRING([--with-libgcrypt], [enable use of libgcrypt instead of OpenSSL])], [])
|
||||||
|
|
||||||
tinc_CURSES
|
tinc_CURSES
|
||||||
tinc_READLINE
|
tinc_READLINE
|
||||||
tinc_LIBEVENT
|
|
||||||
tinc_ZLIB
|
tinc_ZLIB
|
||||||
tinc_LZO
|
tinc_LZO
|
||||||
|
|
||||||
|
|
|
@ -53,10 +53,9 @@ subdir = doc
|
||||||
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in texinfo.tex
|
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in texinfo.tex
|
||||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||||
am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
|
am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
|
||||||
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libevent.m4 \
|
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/lzo.m4 \
|
||||||
$(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \
|
$(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \
|
||||||
$(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \
|
$(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.in
|
||||||
$(top_srcdir)/configure.in
|
|
||||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||||
$(ACLOCAL_M4)
|
$(ACLOCAL_M4)
|
||||||
mkinstalldirs = $(install_sh) -d
|
mkinstalldirs = $(install_sh) -d
|
||||||
|
|
Binary file not shown.
|
@ -3,16 +3,13 @@
|
||||||
.\" Manual page created by:
|
.\" Manual page created by:
|
||||||
.\" Ivo Timmermans
|
.\" Ivo Timmermans
|
||||||
.\" Guus Sliepen <guus@tinc-vpn.org>
|
.\" Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
.Nm tinc.conf
|
.Nm tinc.conf
|
||||||
.Nd tinc daemon configuration
|
.Nd tinc daemon configuration
|
||||||
|
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
The files in the
|
The files in the
|
||||||
.Pa @sysconfdir@/tinc/
|
.Pa @sysconfdir@/tinc/
|
||||||
directory contain runtime and security information for the tinc daemon.
|
directory contain runtime and security information for the tinc daemon.
|
||||||
|
|
||||||
.Sh NETWORKS
|
.Sh NETWORKS
|
||||||
To distinguish multiple instances of tinc running on one computer,
|
To distinguish multiple instances of tinc running on one computer,
|
||||||
you can use the
|
you can use the
|
||||||
|
@ -44,31 +41,26 @@ the configuration file should be
|
||||||
.Pa @sysconfdir@/tinc/tinc.conf ,
|
.Pa @sysconfdir@/tinc/tinc.conf ,
|
||||||
and the host configuration files are now expected to be in
|
and the host configuration files are now expected to be in
|
||||||
.Pa @sysconfdir@/tinc/hosts/ .
|
.Pa @sysconfdir@/tinc/hosts/ .
|
||||||
|
|
||||||
.Sh NAMES
|
.Sh NAMES
|
||||||
Each tinc daemon should have a name that is unique in the network which it will be part of.
|
Each tinc daemon should have a name that is unique in the network which it will be part of.
|
||||||
The name will be used by other tinc daemons for identification.
|
The name will be used by other tinc daemons for identification.
|
||||||
The name has to be declared in the
|
The name has to be declared in the
|
||||||
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf
|
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf
|
||||||
file.
|
file.
|
||||||
|
|
||||||
.Pp
|
.Pp
|
||||||
To make things easy,
|
To make things easy,
|
||||||
choose something that will give unique and easy to remember names to your tinc daemon(s).
|
choose something that will give unique and easy to remember names to your tinc daemon(s).
|
||||||
You could try things like hostnames, owner surnames or location names.
|
You could try things like hostnames, owner surnames or location names.
|
||||||
However, you are only allowed to use alphanumerical characters (a-z, A-Z, and 0-9) and underscores (_) in the name.
|
However, you are only allowed to use alphanumerical characters (a-z, A-Z, and 0-9) and underscores (_) in the name.
|
||||||
|
|
||||||
.Sh INITIAL CONFIGURATION
|
.Sh INITIAL CONFIGURATION
|
||||||
If you have not configured tinc yet, you can easily create a basic configuration using the following command:
|
If you have not configured tinc yet, you can easily create a basic configuration using the following command:
|
||||||
.Bd -literal -offset indent
|
.Bd -literal -offset indent
|
||||||
.Nm tincctl Fl n Ar NETNAME Li init Ar NAME
|
.Nm tincctl Fl n Ar NETNAME Li init Ar NAME
|
||||||
.Ed
|
.Ed
|
||||||
|
|
||||||
.Pp
|
.Pp
|
||||||
You can further change the configuration as needed either by manually editing the configuration files,
|
You can further change the configuration as needed either by manually editing the configuration files,
|
||||||
or by using
|
or by using
|
||||||
.Xr tincctl 8 .
|
.Xr tincctl 8 .
|
||||||
|
|
||||||
.Sh PUBLIC/PRIVATE KEYS
|
.Sh PUBLIC/PRIVATE KEYS
|
||||||
The
|
The
|
||||||
.Nm tincctl Li init
|
.Nm tincctl Li init
|
||||||
|
@ -81,24 +73,20 @@ in the directory
|
||||||
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /
|
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /
|
||||||
The public keys should be stored in the host configuration file
|
The public keys should be stored in the host configuration file
|
||||||
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Ns Va NAME .
|
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Ns Va NAME .
|
||||||
|
|
||||||
The RSA keys are used for backwards compatibility with tinc version 1.0.
|
The RSA keys are used for backwards compatibility with tinc version 1.0.
|
||||||
If you are upgrading from version 1.0 to 1.1, you can keep the old configuration files,
|
If you are upgrading from version 1.0 to 1.1, you can keep the old configuration files,
|
||||||
but you will need to create ECDSA keys using the following command:
|
but you will need to create ECDSA keys using the following command:
|
||||||
.Bd -literal -offset indent
|
.Bd -literal -offset indent
|
||||||
.Nm tincctl Fl n Ar NETNAME Li generate-ecdsa-keys
|
.Nm tincctl Fl n Ar NETNAME Li generate-ecdsa-keys
|
||||||
.Ed
|
.Ed
|
||||||
|
|
||||||
.Sh SERVER CONFIGURATION
|
.Sh SERVER CONFIGURATION
|
||||||
The server configuration of the daemon is done in the file
|
The server configuration of the daemon is done in the file
|
||||||
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf .
|
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf .
|
||||||
This file consists of comments (lines started with a
|
This file consists of comments (lines started with a
|
||||||
.Li # )
|
.Li # )
|
||||||
or assignments in the form of:
|
or assignments in the form of:
|
||||||
|
|
||||||
.Pp
|
.Pp
|
||||||
.Va Variable Li = Ar Value .
|
.Va Variable Li = Ar Value .
|
||||||
|
|
||||||
.Pp
|
.Pp
|
||||||
The variable names are case insensitive, and any spaces, tabs,
|
The variable names are case insensitive, and any spaces, tabs,
|
||||||
newlines and carriage returns are ignored.
|
newlines and carriage returns are ignored.
|
||||||
|
@ -106,31 +94,35 @@ Note: it is not required that you put in the
|
||||||
.Li =
|
.Li =
|
||||||
sign, but doing so improves readability.
|
sign, but doing so improves readability.
|
||||||
If you leave it out, remember to replace it with at least one space character.
|
If you leave it out, remember to replace it with at least one space character.
|
||||||
|
|
||||||
.Pp
|
.Pp
|
||||||
The server configuration is complemented with host specific configuration (see the next section).
|
The server configuration is complemented with host specific configuration (see the next section).
|
||||||
Although all configuration options for the local host listed in this document can also be put in
|
Although all configuration options for the local host listed in this document can also be put in
|
||||||
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf ,
|
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf ,
|
||||||
it is recommended to put host specific configuration options in the host configuration file,
|
it is recommended to put host specific configuration options in the host configuration file,
|
||||||
as this makes it easy to exchange with other nodes.
|
as this makes it easy to exchange with other nodes.
|
||||||
|
|
||||||
.Pp
|
.Pp
|
||||||
You can edit the config file manually, but it is recommended that you use
|
You can edit the config file manually, but it is recommended that you use
|
||||||
.Xr tincctl 8
|
.Xr tincctl 8
|
||||||
to change configuration variables for you.
|
to change configuration variables for you.
|
||||||
|
|
||||||
.Pp
|
.Pp
|
||||||
Here are all valid variables, listed in alphabetical order.
|
Here are all valid variables, listed in alphabetical order.
|
||||||
The default value is given between parentheses.
|
The default value is given between parentheses.
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
|
|
||||||
.It Va AddressFamily Li = ipv4 | ipv6 | any Pq any
|
.It Va AddressFamily Li = ipv4 | ipv6 | any Pq any
|
||||||
This option affects the address family of listening and outgoing sockets.
|
This option affects the address family of listening and outgoing sockets.
|
||||||
If
|
If
|
||||||
.Qq any
|
.Qq any
|
||||||
is selected, then depending on the operating system both IPv4 and IPv6 or just
|
is selected, then depending on the operating system both IPv4 and IPv6 or just
|
||||||
IPv6 listening sockets will be created.
|
IPv6 listening sockets will be created.
|
||||||
|
.It Va AutoConnect Li = Ar count Po 0 Pc Bq experimental
|
||||||
|
If set to a non-zero value,
|
||||||
|
.Nm
|
||||||
|
will try to only have
|
||||||
|
.Ar count
|
||||||
|
meta connections to other nodes,
|
||||||
|
by automatically making or breaking connections to known nodes.
|
||||||
|
Higher values increase redundancy but also increase meta data overhead.
|
||||||
|
When using this option, a good value is 3.
|
||||||
.It Va BindToAddress Li = Ar address Op Ar port
|
.It Va BindToAddress Li = Ar address Op Ar port
|
||||||
If your computer has more than one IPv4 or IPv6 address,
|
If your computer has more than one IPv4 or IPv6 address,
|
||||||
.Nm tinc
|
.Nm tinc
|
||||||
|
@ -149,38 +141,31 @@ To only bind to a specific port but not to a specific address, use
|
||||||
.Li *
|
.Li *
|
||||||
for the
|
for the
|
||||||
.Ar address .
|
.Ar address .
|
||||||
|
|
||||||
.It Va BindToInterface Li = Ar interface Bq experimental
|
.It Va BindToInterface Li = Ar interface Bq experimental
|
||||||
If your computer has more than one network interface,
|
If your computer has more than one network interface,
|
||||||
.Nm tinc
|
.Nm tinc
|
||||||
will by default listen on all of them for incoming connections.
|
will by default listen on all of them for incoming connections.
|
||||||
It is possible to bind only to a single interface with this variable.
|
It is possible to bind only to a single interface with this variable.
|
||||||
|
|
||||||
.Pp
|
.Pp
|
||||||
This option may not work on all platforms.
|
This option may not work on all platforms.
|
||||||
Also, on some platforms it will not actually bind to an interface,
|
Also, on some platforms it will not actually bind to an interface,
|
||||||
but rather to the address that the interface has at the moment a socket is created.
|
but rather to the address that the interface has at the moment a socket is created.
|
||||||
|
|
||||||
.It Va Broadcast Li = no | mst | direct Po mst Pc Bq experimental
|
.It Va Broadcast Li = no | mst | direct Po mst Pc Bq experimental
|
||||||
This option selects the way broadcast packets are sent to other daemons.
|
This option selects the way broadcast packets are sent to other daemons.
|
||||||
NOTE: all nodes in a VPN must use the same
|
NOTE: all nodes in a VPN must use the same
|
||||||
.Va Broadcast
|
.Va Broadcast
|
||||||
mode, otherwise routing loops can form.
|
mode, otherwise routing loops can form.
|
||||||
|
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
.It no
|
.It no
|
||||||
Broadcast packets are never sent to other nodes.
|
Broadcast packets are never sent to other nodes.
|
||||||
|
|
||||||
.It mst
|
.It mst
|
||||||
Broadcast packets are sent and forwarded via the VPN's Minimum Spanning Tree.
|
Broadcast packets are sent and forwarded via the VPN's Minimum Spanning Tree.
|
||||||
This ensures broadcast packets reach all nodes.
|
This ensures broadcast packets reach all nodes.
|
||||||
|
|
||||||
.It direct
|
.It direct
|
||||||
Broadcast packets are sent directly to all nodes that can be reached directly.
|
Broadcast packets are sent directly to all nodes that can be reached directly.
|
||||||
Broadcast packets received from other nodes are never forwarded.
|
Broadcast packets received from other nodes are never forwarded.
|
||||||
If the IndirectData option is also set, broadcast packets will only be sent to nodes which we have a meta connection to.
|
If the IndirectData option is also set, broadcast packets will only be sent to nodes which we have a meta connection to.
|
||||||
.El
|
.El
|
||||||
|
|
||||||
.It Va ConnectTo Li = Ar name
|
.It Va ConnectTo Li = Ar name
|
||||||
Specifies which other tinc daemon to connect to on startup.
|
Specifies which other tinc daemon to connect to on startup.
|
||||||
Multiple
|
Multiple
|
||||||
|
@ -191,14 +176,12 @@ The names should be known to this tinc daemon
|
||||||
(i.e., there should be a host configuration file for the name on the
|
(i.e., there should be a host configuration file for the name on the
|
||||||
.Va ConnectTo
|
.Va ConnectTo
|
||||||
line).
|
line).
|
||||||
|
|
||||||
.Pp
|
.Pp
|
||||||
If you don't specify a host with
|
If you don't specify a host with
|
||||||
.Va ConnectTo ,
|
.Va ConnectTo ,
|
||||||
.Nm tinc
|
.Nm tinc
|
||||||
won't try to connect to other daemons at all,
|
won't try to connect to other daemons at all,
|
||||||
and will instead just listen for incoming connections.
|
and will instead just listen for incoming connections.
|
||||||
|
|
||||||
.It Va DecrementTTL Li = yes | no Po no Pc Bq experimental
|
.It Va DecrementTTL Li = yes | no Po no Pc Bq experimental
|
||||||
When enabled,
|
When enabled,
|
||||||
.Nm tinc
|
.Nm tinc
|
||||||
|
@ -208,7 +191,6 @@ and will drop packets that have a TTL value of zero,
|
||||||
in which case it will send an ICMP Time Exceeded packet back.
|
in which case it will send an ICMP Time Exceeded packet back.
|
||||||
.Pp
|
.Pp
|
||||||
Do not use this option if you use switch mode and want to use IPv6.
|
Do not use this option if you use switch mode and want to use IPv6.
|
||||||
|
|
||||||
.It Va Device Li = Ar device Po Pa /dev/tap0 , Pa /dev/net/tun No or other depending on platform Pc
|
.It Va Device Li = Ar device Po Pa /dev/tap0 , Pa /dev/net/tun No or other depending on platform Pc
|
||||||
The virtual network device to use.
|
The virtual network device to use.
|
||||||
.Nm tinc
|
.Nm tinc
|
||||||
|
@ -220,18 +202,15 @@ instead of
|
||||||
.Va Device .
|
.Va Device .
|
||||||
The info pages of the tinc package contain more information
|
The info pages of the tinc package contain more information
|
||||||
about configuring the virtual network device.
|
about configuring the virtual network device.
|
||||||
|
|
||||||
.It Va DeviceType Li = Ar type Pq platform dependent
|
.It Va DeviceType Li = Ar type Pq platform dependent
|
||||||
The type of the virtual network device.
|
The type of the virtual network device.
|
||||||
Tinc will normally automatically select the right type of tun/tap interface, and this option should not be used.
|
Tinc will normally automatically select the right type of tun/tap interface, and this option should not be used.
|
||||||
However, this option can be used to select one of the special interface types, if support for them is compiled in.
|
However, this option can be used to select one of the special interface types, if support for them is compiled in.
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
|
|
||||||
.It dummy
|
.It dummy
|
||||||
Use a dummy interface.
|
Use a dummy interface.
|
||||||
No packets are ever read or written to a virtual network device.
|
No packets are ever read or written to a virtual network device.
|
||||||
Useful for testing, or when setting up a node that only forwards packets for other nodes.
|
Useful for testing, or when setting up a node that only forwards packets for other nodes.
|
||||||
|
|
||||||
.It raw_socket
|
.It raw_socket
|
||||||
Open a raw socket, and bind it to a pre-existing
|
Open a raw socket, and bind it to a pre-existing
|
||||||
.Va Interface
|
.Va Interface
|
||||||
|
@ -239,7 +218,6 @@ Open a raw socket, and bind it to a pre-existing
|
||||||
All packets are read from this interface.
|
All packets are read from this interface.
|
||||||
Packets received for the local node are written to the raw socket.
|
Packets received for the local node are written to the raw socket.
|
||||||
However, at least on Linux, the operating system does not process IP packets destined for the local host.
|
However, at least on Linux, the operating system does not process IP packets destined for the local host.
|
||||||
|
|
||||||
.It multicast
|
.It multicast
|
||||||
Open a multicast UDP socket and bind it to the address and port (separated by spaces) and optionally a TTL value specified using
|
Open a multicast UDP socket and bind it to the address and port (separated by spaces) and optionally a TTL value specified using
|
||||||
.Va Device .
|
.Va Device .
|
||||||
|
@ -249,7 +227,6 @@ Do NOT connect multiple
|
||||||
.Nm tinc
|
.Nm tinc
|
||||||
daemons to the same multicast address, this will very likely cause routing loops.
|
daemons to the same multicast address, this will very likely cause routing loops.
|
||||||
Also note that this can cause decrypted VPN packets to be sent out on a real network if misconfigured.
|
Also note that this can cause decrypted VPN packets to be sent out on a real network if misconfigured.
|
||||||
|
|
||||||
.It uml Pq not compiled in by default
|
.It uml Pq not compiled in by default
|
||||||
Create a UNIX socket with the filename specified by
|
Create a UNIX socket with the filename specified by
|
||||||
.Va Device ,
|
.Va Device ,
|
||||||
|
@ -258,7 +235,6 @@ or
|
||||||
if not specified.
|
if not specified.
|
||||||
.Nm tinc
|
.Nm tinc
|
||||||
will wait for a User Mode Linux instance to connect to this socket.
|
will wait for a User Mode Linux instance to connect to this socket.
|
||||||
|
|
||||||
.It vde Pq not compiled in by default
|
.It vde Pq not compiled in by default
|
||||||
Uses the libvdeplug library to connect to a Virtual Distributed Ethernet switch,
|
Uses the libvdeplug library to connect to a Virtual Distributed Ethernet switch,
|
||||||
using the UNIX socket specified by
|
using the UNIX socket specified by
|
||||||
|
@ -267,46 +243,37 @@ or
|
||||||
.Pa @localstatedir@/run/vde.ctl
|
.Pa @localstatedir@/run/vde.ctl
|
||||||
if not specified.
|
if not specified.
|
||||||
.El
|
.El
|
||||||
|
|
||||||
Also, in case tinc does not seem to correctly interpret packets received from the virtual network device,
|
Also, in case tinc does not seem to correctly interpret packets received from the virtual network device,
|
||||||
it can be used to change the way packets are interpreted:
|
it can be used to change the way packets are interpreted:
|
||||||
|
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
|
|
||||||
.It tun Pq BSD and Linux
|
.It tun Pq BSD and Linux
|
||||||
Set type to tun.
|
Set type to tun.
|
||||||
Depending on the platform, this can either be with or without an address family header (see below).
|
Depending on the platform, this can either be with or without an address family header (see below).
|
||||||
|
|
||||||
.It tunnohead Pq BSD
|
.It tunnohead Pq BSD
|
||||||
Set type to tun without an address family header.
|
Set type to tun without an address family header.
|
||||||
Tinc will expect packets read from the virtual network device to start with an IP header.
|
Tinc will expect packets read from the virtual network device to start with an IP header.
|
||||||
On some platforms IPv6 packets cannot be read from or written to the device in this mode.
|
On some platforms IPv6 packets cannot be read from or written to the device in this mode.
|
||||||
|
|
||||||
.It tunifhead Pq BSD
|
.It tunifhead Pq BSD
|
||||||
Set type to tun with an address family header.
|
Set type to tun with an address family header.
|
||||||
Tinc will expect packets read from the virtual network device
|
Tinc will expect packets read from the virtual network device
|
||||||
to start with a four byte header containing the address family,
|
to start with a four byte header containing the address family,
|
||||||
followed by an IP header.
|
followed by an IP header.
|
||||||
This mode should support both IPv4 and IPv6 packets.
|
This mode should support both IPv4 and IPv6 packets.
|
||||||
|
|
||||||
.It tap Pq BSD and Linux
|
.It tap Pq BSD and Linux
|
||||||
Set type to tap.
|
Set type to tap.
|
||||||
Tinc will expect packets read from the virtual network device
|
Tinc will expect packets read from the virtual network device
|
||||||
to start with an Ethernet header.
|
to start with an Ethernet header.
|
||||||
.El
|
.El
|
||||||
|
|
||||||
.It Va DirectOnly Li = yes | no Po no Pc Bq experimental
|
.It Va DirectOnly Li = yes | no Po no Pc Bq experimental
|
||||||
When this option is enabled, packets that cannot be sent directly to the destination node,
|
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.
|
but which would have to be forwarded by an intermediate node, are dropped instead.
|
||||||
When combined with the IndirectData option,
|
When combined with the IndirectData option,
|
||||||
packets for nodes for which we do not have a meta connection with are also dropped.
|
packets for nodes for which we do not have a meta connection with are also dropped.
|
||||||
|
|
||||||
.It Va ECDSAPrivateKeyFile Li = Ar filename Po Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /ecdsa_key.priv Pc
|
.It Va ECDSAPrivateKeyFile Li = Ar filename Po Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /ecdsa_key.priv Pc
|
||||||
The file in which the private ECDSA key of this tinc daemon resides.
|
The file in which the private ECDSA key of this tinc daemon resides.
|
||||||
This is only used if
|
This is only used if
|
||||||
.Va ExperimentalProtocol
|
.Va ExperimentalProtocol
|
||||||
is enabled.
|
is enabled.
|
||||||
|
|
||||||
.It Va ExperimentalProtocol Li = yes | no Po no Pc Bq experimental
|
.It Va ExperimentalProtocol Li = yes | no Po no Pc Bq experimental
|
||||||
When this option is enabled, experimental protocol enhancements will be used.
|
When this option is enabled, experimental protocol enhancements will be used.
|
||||||
Ephemeral ECDH will be used for key exchanges,
|
Ephemeral ECDH will be used for key exchanges,
|
||||||
|
@ -315,53 +282,31 @@ When enabled, an ECDSA key must have been generated before with
|
||||||
.Nm tincctl generate-ecdsa-keys .
|
.Nm tincctl generate-ecdsa-keys .
|
||||||
The experimental protocol may change at any time,
|
The experimental protocol may change at any time,
|
||||||
and there is no guarantee that tinc will run stable when it is used.
|
and there is no guarantee that tinc will run stable when it is used.
|
||||||
|
|
||||||
.It Va Forwarding Li = off | internal | kernel Po internal Pc Bq experimental
|
.It Va Forwarding Li = off | internal | kernel Po internal Pc Bq experimental
|
||||||
This option selects the way indirect packets are forwarded.
|
This option selects the way indirect packets are forwarded.
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
|
|
||||||
.It off
|
.It off
|
||||||
Incoming packets that are not meant for the local node,
|
Incoming packets that are not meant for the local node,
|
||||||
but which should be forwarded to another node, are dropped.
|
but which should be forwarded to another node, are dropped.
|
||||||
|
|
||||||
.It internal
|
.It internal
|
||||||
Incoming packets that are meant for another node are forwarded by tinc internally.
|
Incoming packets that are meant for another node are forwarded by tinc internally.
|
||||||
|
|
||||||
.Pp
|
.Pp
|
||||||
This is the default mode, and unless you really know you need another forwarding mode, don't change it.
|
This is the default mode, and unless you really know you need another forwarding mode, don't change it.
|
||||||
|
|
||||||
.It kernel
|
.It kernel
|
||||||
Incoming packets are always sent to the TUN/TAP device, even if the packets are not for the local node.
|
Incoming packets are always sent to the TUN/TAP device, even if the packets are not for the local node.
|
||||||
This is less efficient, but allows the kernel to apply its routing and firewall rules on them,
|
This is less efficient, but allows the kernel to apply its routing and firewall rules on them,
|
||||||
and can also help debugging.
|
and can also help debugging.
|
||||||
.El
|
.El
|
||||||
|
|
||||||
.It Va GraphDumpFile Li = Ar filename
|
|
||||||
If this option is present,
|
|
||||||
.Nm tinc
|
|
||||||
will dump the current network graph to the file
|
|
||||||
.Ar filename
|
|
||||||
every minute, unless there were no changes to the graph.
|
|
||||||
The file is in a format that can be read by graphviz tools.
|
|
||||||
If
|
|
||||||
.Ar filename
|
|
||||||
starts with a pipe symbol |,
|
|
||||||
then the rest of the filename is interpreted as a shell command
|
|
||||||
that is executed, the graph is then sent to stdin.
|
|
||||||
|
|
||||||
.It Va Hostnames Li = yes | no Pq no
|
.It Va Hostnames Li = yes | no Pq no
|
||||||
This option selects whether IP addresses (both real and on the VPN) should
|
This option selects whether IP addresses (both real and on the VPN) should
|
||||||
be resolved. Since DNS lookups are blocking, it might affect tinc's
|
be resolved. Since DNS lookups are blocking, it might affect tinc's
|
||||||
efficiency, even stopping the daemon for a few seconds every time it does
|
efficiency, even stopping the daemon for a few seconds every time it does
|
||||||
a lookup if your DNS server is not responding.
|
a lookup if your DNS server is not responding.
|
||||||
|
|
||||||
.Pp
|
.Pp
|
||||||
This does not affect resolving hostnames to IP addresses from the
|
This does not affect resolving hostnames to IP addresses from the
|
||||||
host configuration files, but whether hostnames should be resolved while logging.
|
host configuration files, but whether hostnames should be resolved while logging.
|
||||||
|
|
||||||
.It Va IffOneQueue Li = yes | no Po no Pc Bq experimental
|
.It Va IffOneQueue Li = yes | no Po no Pc Bq experimental
|
||||||
(Linux only) Set IFF_ONE_QUEUE flag on TUN/TAP devices.
|
(Linux only) Set IFF_ONE_QUEUE flag on TUN/TAP devices.
|
||||||
|
|
||||||
.It Va Interface Li = Ar interface
|
.It Va Interface Li = Ar interface
|
||||||
Defines the name of the interface corresponding to the virtual network device.
|
Defines the name of the interface corresponding to the virtual network device.
|
||||||
Depending on the operating system and the type of device this may or may not actually set the name of the interface.
|
Depending on the operating system and the type of device this may or may not actually set the name of the interface.
|
||||||
|
@ -369,12 +314,10 @@ Under Windows, this variable is used to select which network interface will be u
|
||||||
If you specified a
|
If you specified a
|
||||||
.Va Device ,
|
.Va Device ,
|
||||||
this variable is almost always already correctly set.
|
this variable is almost always already correctly set.
|
||||||
|
|
||||||
.It Va KeyExpire Li = Ar seconds Pq 3600
|
.It Va KeyExpire Li = Ar seconds Pq 3600
|
||||||
This option controls the period the encryption keys used to encrypt the data are valid.
|
This option controls the period the encryption keys used to encrypt the data are valid.
|
||||||
It is common practice to change keys at regular intervals to make it even harder for crackers,
|
It is common practice to change keys at regular intervals to make it even harder for crackers,
|
||||||
even though it is thought to be nearly impossible to crack a single key.
|
even though it is thought to be nearly impossible to crack a single key.
|
||||||
|
|
||||||
.It Va LocalDiscovery Li = yes | no Pq no
|
.It Va LocalDiscovery Li = yes | no Pq no
|
||||||
When enabled,
|
When enabled,
|
||||||
.Nm tinc
|
.Nm tinc
|
||||||
|
@ -382,54 +325,43 @@ will try to detect peers that are on the same local network.
|
||||||
This will allow direct communication using LAN addresses, even if both peers are behind a NAT
|
This will allow direct communication using LAN addresses, even if both peers are behind a NAT
|
||||||
and they only ConnectTo a third node outside the NAT,
|
and they only ConnectTo a third node outside the NAT,
|
||||||
which normally would prevent the peers from learning each other's LAN address.
|
which normally would prevent the peers from learning each other's LAN address.
|
||||||
|
|
||||||
.Pp
|
.Pp
|
||||||
Currently, local discovery is implemented by sending broadcast packets to the LAN during path MTU discovery.
|
Currently, local discovery is implemented by sending broadcast packets to the LAN during path MTU discovery.
|
||||||
This feature may not work in all possible situations.
|
This feature may not work in all possible situations.
|
||||||
|
|
||||||
.It Va MACExpire Li = Ar seconds Pq 600
|
.It Va MACExpire Li = Ar seconds Pq 600
|
||||||
This option controls the amount of time MAC addresses are kept before they are removed.
|
This option controls the amount of time MAC addresses are kept before they are removed.
|
||||||
This only has effect when
|
This only has effect when
|
||||||
.Va Mode
|
.Va Mode
|
||||||
is set to
|
is set to
|
||||||
.Qq switch .
|
.Qq switch .
|
||||||
|
|
||||||
.It Va MaxTimeout Li = Ar seconds Pq 900
|
.It Va MaxTimeout Li = Ar seconds Pq 900
|
||||||
This is the maximum delay before trying to reconnect to other tinc daemons.
|
This is the maximum delay before trying to reconnect to other tinc daemons.
|
||||||
|
|
||||||
.It Va Mode Li = router | switch | hub Pq router
|
.It Va Mode Li = router | switch | hub Pq router
|
||||||
This option selects the way packets are routed to other daemons.
|
This option selects the way packets are routed to other daemons.
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
|
|
||||||
.It router
|
.It router
|
||||||
In this mode
|
In this mode
|
||||||
.Va Subnet
|
.Va Subnet
|
||||||
variables in the host configuration files will be used to form a routing table.
|
variables in the host configuration files will be used to form a routing table.
|
||||||
Only unicast packets of routable protocols (IPv4 and IPv6) are supported in this mode.
|
Only unicast packets of routable protocols (IPv4 and IPv6) are supported in this mode.
|
||||||
|
|
||||||
.Pp
|
.Pp
|
||||||
This is the default mode, and unless you really know you need another mode, don't change it.
|
This is the default mode, and unless you really know you need another mode, don't change it.
|
||||||
|
|
||||||
.It switch
|
.It switch
|
||||||
In this mode the MAC addresses of the packets on the VPN will be used to
|
In this mode the MAC addresses of the packets on the VPN will be used to
|
||||||
dynamically create a routing table just like an Ethernet switch does.
|
dynamically create a routing table just like an Ethernet switch does.
|
||||||
Unicast, multicast and broadcast packets of every protocol that runs over Ethernet are supported in this mode
|
Unicast, multicast and broadcast packets of every protocol that runs over Ethernet are supported in this mode
|
||||||
at the cost of frequent broadcast ARP requests and routing table updates.
|
at the cost of frequent broadcast ARP requests and routing table updates.
|
||||||
|
|
||||||
.Pp
|
.Pp
|
||||||
This mode is primarily useful if you want to bridge Ethernet segments.
|
This mode is primarily useful if you want to bridge Ethernet segments.
|
||||||
|
|
||||||
.It hub
|
.It hub
|
||||||
This mode is almost the same as the switch mode, but instead
|
This mode is almost the same as the switch mode, but instead
|
||||||
every packet will be broadcast to the other daemons
|
every packet will be broadcast to the other daemons
|
||||||
while no routing table is managed.
|
while no routing table is managed.
|
||||||
.El
|
.El
|
||||||
|
|
||||||
.It Va Name Li = Ar name Bq required
|
.It Va Name Li = Ar name Bq required
|
||||||
This is the name which identifies this tinc daemon.
|
This is the name which identifies this tinc daemon.
|
||||||
It must be unique for the virtual private network this daemon will connect to.
|
It must be unique for the virtual private network this daemon will connect to.
|
||||||
The Name may only consist of alphanumeric and underscore characters.
|
The Name may only consist of alphanumeric and underscore characters.
|
||||||
|
|
||||||
If
|
If
|
||||||
.Va Name
|
.Va Name
|
||||||
starts with a
|
starts with a
|
||||||
|
@ -441,40 +373,28 @@ If
|
||||||
is
|
is
|
||||||
.Li $HOST ,
|
.Li $HOST ,
|
||||||
but no such environment variable exist, the hostname will be read using the gethostnname() system call.
|
but no such environment variable exist, the hostname will be read using the gethostnname() system call.
|
||||||
|
|
||||||
.It Va PingInterval Li = Ar seconds Pq 60
|
.It Va PingInterval Li = Ar seconds Pq 60
|
||||||
The number of seconds of inactivity that
|
The number of seconds of inactivity that
|
||||||
.Nm tinc
|
.Nm tinc
|
||||||
will wait before sending a probe to the other end.
|
will wait before sending a probe to the other end.
|
||||||
|
|
||||||
.It Va PingTimeout Li = Ar seconds Pq 5
|
.It Va PingTimeout Li = Ar seconds Pq 5
|
||||||
The number of seconds to wait for a response to pings or to allow meta
|
The number of seconds to wait for a response to pings or to allow meta
|
||||||
connections to block. If the other end doesn't respond within this time,
|
connections to block. If the other end doesn't respond within this time,
|
||||||
the connection is terminated,
|
the connection is terminated,
|
||||||
and the others will be notified of this.
|
and the others will be notified of this.
|
||||||
|
|
||||||
.It Va PriorityInheritance Li = yes | no Po no Pc Bq experimental
|
.It Va PriorityInheritance Li = yes | no Po no Pc Bq experimental
|
||||||
When this option is enabled the value of the TOS field of tunneled IPv4 packets
|
When this option is enabled the value of the TOS field of tunneled IPv4 packets
|
||||||
will be inherited by the UDP packets that are sent out.
|
will be inherited by the UDP packets that are sent out.
|
||||||
|
|
||||||
.It Va PrivateKey Li = Ar key Bq obsolete
|
.It Va PrivateKey Li = Ar key Bq obsolete
|
||||||
The private RSA key of this tinc daemon.
|
The private RSA key of this tinc daemon.
|
||||||
It will allow this tinc daemon to authenticate itself to other daemons.
|
It will allow this tinc daemon to authenticate itself to other daemons.
|
||||||
|
|
||||||
.It Va PrivateKeyFile Li = Ar filename Po Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /rsa_key.priv Pc
|
.It Va PrivateKeyFile Li = Ar filename Po Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /rsa_key.priv Pc
|
||||||
The file in which the private RSA key of this tinc daemon resides.
|
The file in which the private RSA key of this tinc daemon resides.
|
||||||
Note that there must be exactly one of
|
|
||||||
.Va PrivateKey
|
|
||||||
or
|
|
||||||
.Va PrivateKeyFile
|
|
||||||
specified in the configuration file.
|
|
||||||
|
|
||||||
.It Va ProcessPriority Li = low | normal | high
|
.It Va ProcessPriority Li = low | normal | high
|
||||||
When this option is used the priority of the
|
When this option is used the priority of the
|
||||||
.Nm tincd
|
.Nm tincd
|
||||||
process will be adjusted.
|
process will be adjusted.
|
||||||
Increasing the priority may help to reduce latency and packet loss on the VPN.
|
Increasing the priority may help to reduce latency and packet loss on the VPN.
|
||||||
|
|
||||||
.It Va Proxy Li = socks4 | socks5 | http | exec Ar ... Bq experimental
|
.It Va Proxy Li = socks4 | socks5 | http | exec Ar ... Bq experimental
|
||||||
Use a proxy when making outgoing connections.
|
Use a proxy when making outgoing connections.
|
||||||
The following proxy types are currently supported:
|
The following proxy types are currently supported:
|
||||||
|
@ -507,7 +427,6 @@ and
|
||||||
.Ev REMOTEPORT
|
.Ev REMOTEPORT
|
||||||
are available.
|
are available.
|
||||||
.El
|
.El
|
||||||
|
|
||||||
.It Va ReplayWindow Li = Ar bytes Pq 16
|
.It Va ReplayWindow Li = Ar bytes Pq 16
|
||||||
vhis is the size of the replay tracking window for each remote node, in bytes.
|
vhis is the size of the replay tracking window for each remote node, in bytes.
|
||||||
The window is a bitfield which tracks 1 packet per bit, so for example
|
The window is a bitfield which tracks 1 packet per bit, so for example
|
||||||
|
@ -517,35 +436,29 @@ the interaction of replay tracking with underlying real packet loss and/or
|
||||||
reordering. Setting this to zero will disable replay tracking completely and
|
reordering. Setting this to zero will disable replay tracking completely and
|
||||||
pass all traffic, but leaves tinc vulnerable to replay-based attacks on your
|
pass all traffic, but leaves tinc vulnerable to replay-based attacks on your
|
||||||
traffic.
|
traffic.
|
||||||
|
|
||||||
.It Va StrictSubnets Li = yes | no Po no Pc Bq experimental
|
.It Va StrictSubnets Li = yes | no Po no Pc Bq experimental
|
||||||
When this option is enabled tinc will only use Subnet statements which are
|
When this option is enabled tinc will only use Subnet statements which are
|
||||||
present in the host config files in the local
|
present in the host config files in the local
|
||||||
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/
|
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/
|
||||||
directory.
|
directory.
|
||||||
|
|
||||||
.It Va TunnelServer Li = yes | no Po no Pc Bq experimental
|
.It Va TunnelServer Li = yes | no Po no Pc Bq experimental
|
||||||
When this option is enabled tinc will no longer forward information between other tinc daemons,
|
When this option is enabled tinc will no longer forward information between other tinc daemons,
|
||||||
and will only allow connections with nodes for which host config files are present in the local
|
and will only allow connections with nodes for which host config files are present in the local
|
||||||
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/
|
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/
|
||||||
directory.
|
directory.
|
||||||
Setting this options also implicitly sets StrictSubnets.
|
Setting this options also implicitly sets StrictSubnets.
|
||||||
|
|
||||||
.It Va UDPRcvBuf Li = Ar bytes Pq OS default
|
.It Va UDPRcvBuf Li = Ar bytes Pq OS default
|
||||||
Sets the socket receive buffer size for the UDP socket, in bytes.
|
Sets the socket receive buffer size for the UDP socket, in bytes.
|
||||||
If unset, the default buffer size will be used by the operating system.
|
If unset, the default buffer size will be used by the operating system.
|
||||||
|
|
||||||
.It Va UDPSndBuf Li = Ar bytes Pq OS default
|
.It Va UDPSndBuf Li = Ar bytes Pq OS default
|
||||||
Sets the socket send buffer size for the UDP socket, in bytes.
|
Sets the socket send buffer size for the UDP socket, in bytes.
|
||||||
If unset, the default buffer size will be used by the operating system.
|
If unset, the default buffer size will be used by the operating system.
|
||||||
.El
|
.El
|
||||||
|
|
||||||
.Sh HOST CONFIGURATION FILES
|
.Sh HOST CONFIGURATION FILES
|
||||||
The host configuration files contain all information needed
|
The host configuration files contain all information needed
|
||||||
to establish a connection to those hosts.
|
to establish a connection to those hosts.
|
||||||
A host configuration file is also required for the local tinc daemon,
|
A host configuration file is also required for the local tinc daemon,
|
||||||
it will use it to read in it's listen port, public key and subnets.
|
it will use it to read in it's listen port, public key and subnets.
|
||||||
|
|
||||||
.Pp
|
.Pp
|
||||||
The idea is that these files are portable.
|
The idea is that these files are portable.
|
||||||
You can safely mail your own host configuration file to someone else.
|
You can safely mail your own host configuration file to someone else.
|
||||||
|
@ -554,7 +467,6 @@ and now his tinc daemon will be able to connect to your tinc daemon.
|
||||||
Since host configuration files only contain public keys,
|
Since host configuration files only contain public keys,
|
||||||
no secrets are revealed by sending out this information.
|
no secrets are revealed by sending out this information.
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
|
|
||||||
.It Va Address Li = Ar address Oo Ar port Oc Bq recommended
|
.It Va Address Li = Ar address Oo Ar port Oc Bq recommended
|
||||||
The IP address or hostname of this tinc daemon on the real network.
|
The IP address or hostname of this tinc daemon on the real network.
|
||||||
This will only be used when trying to make an outgoing connection to this tinc daemon.
|
This will only be used when trying to make an outgoing connection to this tinc daemon.
|
||||||
|
@ -563,7 +475,6 @@ Multiple
|
||||||
.Va Address
|
.Va Address
|
||||||
variables can be specified, in which case each address will be tried until a working
|
variables can be specified, in which case each address will be tried until a working
|
||||||
connection has been established.
|
connection has been established.
|
||||||
|
|
||||||
.It Va Cipher Li = Ar cipher Pq blowfish
|
.It Va Cipher Li = Ar cipher Pq blowfish
|
||||||
The symmetric cipher algorithm used to encrypt UDP packets.
|
The symmetric cipher algorithm used to encrypt UDP packets.
|
||||||
Any cipher supported by OpenSSL is recognised.
|
Any cipher supported by OpenSSL is recognised.
|
||||||
|
@ -571,24 +482,20 @@ Furthermore, specifying
|
||||||
.Qq none
|
.Qq none
|
||||||
will turn off packet encryption.
|
will turn off packet encryption.
|
||||||
It is best to use only those ciphers which support CBC mode.
|
It is best to use only those ciphers which support CBC mode.
|
||||||
|
|
||||||
.It Va ClampMSS Li = yes | no Pq yes
|
.It Va ClampMSS Li = yes | no Pq yes
|
||||||
This option specifies whether tinc should clamp the maximum segment size (MSS)
|
This option specifies whether tinc should clamp the maximum segment size (MSS)
|
||||||
of TCP packets to the path MTU. This helps in situations where ICMP
|
of TCP packets to the path MTU. This helps in situations where ICMP
|
||||||
Fragmentation Needed or Packet too Big messages are dropped by firewalls.
|
Fragmentation Needed or Packet too Big messages are dropped by firewalls.
|
||||||
|
|
||||||
.It Va Compression Li = Ar level Pq 0
|
.It Va Compression Li = Ar level Pq 0
|
||||||
This option sets the level of compression used for UDP packets.
|
This option sets the level of compression used for UDP packets.
|
||||||
Possible values are 0 (off), 1 (fast zlib) and any integer up to 9 (best zlib),
|
Possible values are 0 (off), 1 (fast zlib) and any integer up to 9 (best zlib),
|
||||||
10 (fast lzo) and 11 (best lzo).
|
10 (fast lzo) and 11 (best lzo).
|
||||||
|
|
||||||
.It Va Digest Li = Ar digest Pq sha1
|
.It Va Digest Li = Ar digest Pq sha1
|
||||||
The digest algorithm used to authenticate UDP packets.
|
The digest algorithm used to authenticate UDP packets.
|
||||||
Any digest supported by OpenSSL is recognised.
|
Any digest supported by OpenSSL is recognised.
|
||||||
Furthermore, specifying
|
Furthermore, specifying
|
||||||
.Qq none
|
.Qq none
|
||||||
will turn off packet authentication.
|
will turn off packet authentication.
|
||||||
|
|
||||||
.It Va IndirectData Li = yes | no Pq no
|
.It Va IndirectData Li = yes | no Pq no
|
||||||
This option specifies whether other tinc daemons besides the one you specified with
|
This option specifies whether other tinc daemons besides the one you specified with
|
||||||
.Va ConnectTo
|
.Va ConnectTo
|
||||||
|
@ -596,33 +503,26 @@ can make a direct connection to you.
|
||||||
This is especially useful if you are behind a firewall
|
This is especially useful if you are behind a firewall
|
||||||
and it is impossible to make a connection from the outside to your tinc daemon.
|
and it is impossible to make a connection from the outside to your tinc daemon.
|
||||||
Otherwise, it is best to leave this option out or set it to no.
|
Otherwise, it is best to leave this option out or set it to no.
|
||||||
|
|
||||||
.It Va MACLength Li = Ar length Pq 4
|
.It Va MACLength Li = Ar length Pq 4
|
||||||
The length of the message authentication code used to authenticate UDP packets.
|
The length of the message authentication code used to authenticate UDP packets.
|
||||||
Can be anything from
|
Can be anything from
|
||||||
.Qq 0
|
.Qq 0
|
||||||
up to the length of the digest produced by the digest algorithm.
|
up to the length of the digest produced by the digest algorithm.
|
||||||
|
|
||||||
.It Va PMTU Li = Ar mtu Po 1514 Pc
|
.It Va PMTU Li = Ar mtu Po 1514 Pc
|
||||||
This option controls the initial path MTU to this node.
|
This option controls the initial path MTU to this node.
|
||||||
|
|
||||||
.It Va PMTUDiscovery Li = yes | no Po yes Pc
|
.It Va PMTUDiscovery Li = yes | no Po yes Pc
|
||||||
When this option is enabled, tinc will try to discover the path MTU to this node.
|
When this option is enabled, tinc will try to discover the path MTU to this node.
|
||||||
After the path MTU has been discovered, it will be enforced on the VPN.
|
After the path MTU has been discovered, it will be enforced on the VPN.
|
||||||
|
|
||||||
.It Va Port Li = Ar port Pq 655
|
.It Va Port Li = Ar port Pq 655
|
||||||
The port number on which this tinc daemon is listening for incoming connections,
|
The port number on which this tinc daemon is listening for incoming connections,
|
||||||
which is used if no port number is specified in an
|
which is used if no port number is specified in an
|
||||||
.Va Address
|
.Va Address
|
||||||
statement.
|
statement.
|
||||||
|
|
||||||
.It Va PublicKey Li = Ar key Bq obsolete
|
.It Va PublicKey Li = Ar key Bq obsolete
|
||||||
The public RSA key of this tinc daemon.
|
The public RSA key of this tinc daemon.
|
||||||
It will be used to cryptographically verify it's identity and to set up a secure connection.
|
It will be used to cryptographically verify it's identity and to set up a secure connection.
|
||||||
|
|
||||||
.It Va PublicKeyFile Li = Ar filename Bq obsolete
|
.It Va PublicKeyFile Li = Ar filename Bq obsolete
|
||||||
The file in which the public RSA key of this tinc daemon resides.
|
The file in which the public RSA key of this tinc daemon resides.
|
||||||
|
|
||||||
.Pp
|
.Pp
|
||||||
From version 1.0pre4 on
|
From version 1.0pre4 on
|
||||||
.Nm tinc
|
.Nm tinc
|
||||||
|
@ -631,7 +531,6 @@ the above two options then are not necessary.
|
||||||
Either the PEM format is used, or exactly one of the above two options must be specified
|
Either the PEM format is used, or exactly one of the above two options must be specified
|
||||||
in each host configuration file,
|
in each host configuration file,
|
||||||
if you want to be able to establish a connection with that host.
|
if you want to be able to establish a connection with that host.
|
||||||
|
|
||||||
.It Va Subnet Li = Ar address Ns Op Li / Ns Ar prefixlength Ns Op Li # Ns Ar weight
|
.It Va Subnet Li = Ar address Ns Op Li / Ns Ar prefixlength Ns Op Li # Ns Ar weight
|
||||||
The subnet which this tinc daemon will serve.
|
The subnet which this tinc daemon will serve.
|
||||||
.Nm tinc
|
.Nm tinc
|
||||||
|
@ -641,7 +540,6 @@ it will be sent to the daemon who has this subnet in his host configuration file
|
||||||
Multiple
|
Multiple
|
||||||
.Va Subnet
|
.Va Subnet
|
||||||
variables can be specified.
|
variables can be specified.
|
||||||
|
|
||||||
.Pp
|
.Pp
|
||||||
Subnets can either be single MAC, IPv4 or IPv6 addresses,
|
Subnets can either be single MAC, IPv4 or IPv6 addresses,
|
||||||
in which case a subnet consisting of only that single address is assumed,
|
in which case a subnet consisting of only that single address is assumed,
|
||||||
|
@ -652,14 +550,12 @@ Note that subnets like 192.168.1.1/24 are invalid!
|
||||||
Read a networking HOWTO/FAQ/guide if you don't understand this.
|
Read a networking HOWTO/FAQ/guide if you don't understand this.
|
||||||
IPv6 subnets are notated like fec0:0:0:1::/64.
|
IPv6 subnets are notated like fec0:0:0:1::/64.
|
||||||
MAC addresses are notated like 0:1a:2b:3c:4d:5e.
|
MAC addresses are notated like 0:1a:2b:3c:4d:5e.
|
||||||
|
|
||||||
.Pp
|
.Pp
|
||||||
A Subnet can be given a weight to indicate its priority over identical Subnets
|
A Subnet can be given a weight to indicate its priority over identical Subnets
|
||||||
owned by different nodes. The default weight is 10. Lower values indicate
|
owned by different nodes. The default weight is 10. Lower values indicate
|
||||||
higher priority. Packets will be sent to the node with the highest priority,
|
higher priority. Packets will be sent to the node with the highest priority,
|
||||||
unless that node is not reachable, in which case the node with the next highest
|
unless that node is not reachable, in which case the node with the next highest
|
||||||
priority will be tried, and so on.
|
priority will be tried, and so on.
|
||||||
|
|
||||||
.It Va TCPOnly Li = yes | no Pq no Bq obsolete
|
.It Va TCPOnly Li = yes | no Pq no Bq obsolete
|
||||||
If this variable is set to yes,
|
If this variable is set to yes,
|
||||||
then the packets are tunnelled over the TCP connection instead of a UDP connection.
|
then the packets are tunnelled over the TCP connection instead of a UDP connection.
|
||||||
|
@ -667,53 +563,42 @@ This is especially useful for those who want to run a tinc daemon
|
||||||
from behind a masquerading firewall,
|
from behind a masquerading firewall,
|
||||||
or if UDP packet routing is disabled somehow.
|
or if UDP packet routing is disabled somehow.
|
||||||
Setting this options also implicitly sets IndirectData.
|
Setting this options also implicitly sets IndirectData.
|
||||||
|
|
||||||
.Pp
|
.Pp
|
||||||
Since version 1.0.10, tinc will automatically detect whether communication via
|
Since version 1.0.10, tinc will automatically detect whether communication via
|
||||||
UDP is possible or not.
|
UDP is possible or not.
|
||||||
.El
|
.El
|
||||||
|
|
||||||
.Sh SCRIPTS
|
.Sh SCRIPTS
|
||||||
Apart from reading the server and host configuration files,
|
Apart from reading the server and host configuration files,
|
||||||
tinc can also run scripts at certain moments.
|
tinc can also run scripts at certain moments.
|
||||||
Under Windows (not Cygwin), the scripts should have the extension
|
Under Windows (not Cygwin), the scripts should have the extension
|
||||||
.Pa .bat .
|
.Pa .bat .
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
|
|
||||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-up
|
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-up
|
||||||
This is the most important script.
|
This is the most important script.
|
||||||
If it is present it will be executed right after the tinc daemon has been started and has connected to the virtual network device.
|
If it is present it will be executed right after the tinc daemon has been started and has connected to the virtual network device.
|
||||||
It should be used to set up the corresponding network interface,
|
It should be used to set up the corresponding network interface,
|
||||||
but can also be used to start other things.
|
but can also be used to start other things.
|
||||||
Under Windows you can use the Network Connections control panel instead of creating this script.
|
Under Windows you can use the Network Connections control panel instead of creating this script.
|
||||||
|
|
||||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-down
|
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-down
|
||||||
This script is started right before the tinc daemon quits.
|
This script is started right before the tinc daemon quits.
|
||||||
|
|
||||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Ns Ar HOST Ns Pa -up
|
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Ns Ar HOST Ns Pa -up
|
||||||
This script is started when the tinc daemon with name
|
This script is started when the tinc daemon with name
|
||||||
.Ar HOST
|
.Ar HOST
|
||||||
becomes reachable.
|
becomes reachable.
|
||||||
|
|
||||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Ns Ar HOST Ns Pa -down
|
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Ns Ar HOST Ns Pa -down
|
||||||
This script is started when the tinc daemon with name
|
This script is started when the tinc daemon with name
|
||||||
.Ar HOST
|
.Ar HOST
|
||||||
becomes unreachable.
|
becomes unreachable.
|
||||||
|
|
||||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /host-up
|
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /host-up
|
||||||
This script is started when any host becomes reachable.
|
This script is started when any host becomes reachable.
|
||||||
|
|
||||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /host-down
|
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /host-down
|
||||||
This script is started when any host becomes unreachable.
|
This script is started when any host becomes unreachable.
|
||||||
|
|
||||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /subnet-up
|
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /subnet-up
|
||||||
This script is started when a Subnet becomes reachable.
|
This script is started when a Subnet becomes reachable.
|
||||||
The Subnet and the node it belongs to are passed in environment variables.
|
The Subnet and the node it belongs to are passed in environment variables.
|
||||||
|
|
||||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /subnet-down
|
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /subnet-down
|
||||||
This script is started when a Subnet becomes unreachable.
|
This script is started when a Subnet becomes unreachable.
|
||||||
.El
|
.El
|
||||||
|
|
||||||
.Pp
|
.Pp
|
||||||
The scripts are started without command line arguments, but can make use of certain environment variables.
|
The scripts are started without command line arguments, but can make use of certain environment variables.
|
||||||
Under UNIX like operating systems the names of environment variables must be preceded by a
|
Under UNIX like operating systems the names of environment variables must be preceded by a
|
||||||
|
@ -725,73 +610,55 @@ files, they have to be put between
|
||||||
.Li %
|
.Li %
|
||||||
signs.
|
signs.
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
|
|
||||||
.It Ev NETNAME
|
.It Ev NETNAME
|
||||||
If a netname was specified, this environment variable contains it.
|
If a netname was specified, this environment variable contains it.
|
||||||
|
|
||||||
.It Ev NAME
|
.It Ev NAME
|
||||||
Contains the name of this tinc daemon.
|
Contains the name of this tinc daemon.
|
||||||
|
|
||||||
.It Ev DEVICE
|
.It Ev DEVICE
|
||||||
Contains the name of the virtual network device that tinc uses.
|
Contains the name of the virtual network device that tinc uses.
|
||||||
|
|
||||||
.It Ev INTERFACE
|
.It Ev INTERFACE
|
||||||
Contains the name of the virtual network interface that tinc uses.
|
Contains the name of the virtual network interface that tinc uses.
|
||||||
This should be used for commands like
|
This should be used for commands like
|
||||||
.Pa ifconfig .
|
.Pa ifconfig .
|
||||||
|
|
||||||
.It Ev NODE
|
.It Ev NODE
|
||||||
When a host becomes (un)reachable, this is set to its name.
|
When a host becomes (un)reachable, this is set to its name.
|
||||||
If a subnet becomes (un)reachable, this is set to the owner of that subnet.
|
If a subnet becomes (un)reachable, this is set to the owner of that subnet.
|
||||||
|
|
||||||
.It Ev REMOTEADDRESS
|
.It Ev REMOTEADDRESS
|
||||||
When a host becomes (un)reachable, this is set to its real address.
|
When a host becomes (un)reachable, this is set to its real address.
|
||||||
|
|
||||||
.It Ev REMOTEPORT
|
.It Ev REMOTEPORT
|
||||||
When a host becomes (un)reachable, this is set to the port number it uses for communication with other tinc daemons.
|
When a host becomes (un)reachable, this is set to the port number it uses for communication with other tinc daemons.
|
||||||
|
|
||||||
.It Ev SUBNET
|
.It Ev SUBNET
|
||||||
When a subnet becomes (un)reachable, this is set to the subnet.
|
When a subnet becomes (un)reachable, this is set to the subnet.
|
||||||
|
|
||||||
.It Ev WEIGHT
|
.It Ev WEIGHT
|
||||||
When a subnet becomes (un)reachable, this is set to the subnet weight.
|
When a subnet becomes (un)reachable, this is set to the subnet weight.
|
||||||
.El
|
.El
|
||||||
|
|
||||||
.Pp
|
.Pp
|
||||||
Do not forget that under UNIX operating systems, you have to make the scripts executable, using the command
|
Do not forget that under UNIX operating systems, you have to make the scripts executable, using the command
|
||||||
.Nm chmod Li a+x Pa script .
|
.Nm chmod Li a+x Pa script .
|
||||||
|
|
||||||
.Sh FILES
|
.Sh FILES
|
||||||
The most important files are:
|
The most important files are:
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
|
|
||||||
.It Pa @sysconfdir@/tinc/
|
.It Pa @sysconfdir@/tinc/
|
||||||
The top directory for configuration files.
|
The top directory for configuration files.
|
||||||
|
|
||||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf
|
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf
|
||||||
The default name of the server configuration file for net
|
The default name of the server configuration file for net
|
||||||
.Ar NETNAME .
|
.Ar NETNAME .
|
||||||
|
|
||||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/
|
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/
|
||||||
Host configuration files are kept in this directory.
|
Host configuration files are kept in this directory.
|
||||||
|
|
||||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-up
|
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-up
|
||||||
If an executable file with this name exists,
|
If an executable file with this name exists,
|
||||||
it will be executed right after the tinc daemon has connected to the virtual network device.
|
it will be executed right after the tinc daemon has connected to the virtual network device.
|
||||||
It can be used to set up the corresponding network interface.
|
It can be used to set up the corresponding network interface.
|
||||||
|
|
||||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-down
|
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-down
|
||||||
If an executable file with this name exists,
|
If an executable file with this name exists,
|
||||||
it will be executed right before the tinc daemon is going to close
|
it will be executed right before the tinc daemon is going to close
|
||||||
its connection to the virtual network device.
|
its connection to the virtual network device.
|
||||||
.El
|
.El
|
||||||
|
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr tincd 8 ,
|
.Xr tincd 8 ,
|
||||||
.Xr tincctl 8 ,
|
.Xr tincctl 8 ,
|
||||||
.Pa http://www.tinc-vpn.org/ ,
|
.Pa http://www.tinc-vpn.org/ ,
|
||||||
.Pa http://www.tldp.org/LDP/nag2/ .
|
.Pa http://www.tldp.org/LDP/nag2/ .
|
||||||
|
|
||||||
.Pp
|
.Pp
|
||||||
The full documentation for
|
The full documentation for
|
||||||
.Nm tinc
|
.Nm tinc
|
||||||
|
@ -799,7 +666,6 @@ is maintained as a Texinfo manual.
|
||||||
If the info and tinc programs are properly installed at your site, the command
|
If the info and tinc programs are properly installed at your site, the command
|
||||||
.Ic info tinc
|
.Ic info tinc
|
||||||
should give you access to the complete manual.
|
should give you access to the complete manual.
|
||||||
|
|
||||||
.Pp
|
.Pp
|
||||||
.Nm tinc
|
.Nm tinc
|
||||||
comes with ABSOLUTELY NO WARRANTY.
|
comes with ABSOLUTELY NO WARRANTY.
|
||||||
|
|
304
doc/tinc.info
304
doc/tinc.info
|
@ -5,7 +5,7 @@ START-INFO-DIR-ENTRY
|
||||||
* tinc: (tinc). The tinc Manual.
|
* tinc: (tinc). The tinc Manual.
|
||||||
END-INFO-DIR-ENTRY
|
END-INFO-DIR-ENTRY
|
||||||
|
|
||||||
This is the info manual for tinc version 1.1pre2, a Virtual Private
|
This is the info manual for tinc version 1.1pre4, a Virtual Private
|
||||||
Network daemon.
|
Network daemon.
|
||||||
|
|
||||||
Copyright (C) 1998-2012 Ivo Timmermans, Guus Sliepen
|
Copyright (C) 1998-2012 Ivo Timmermans, Guus Sliepen
|
||||||
|
@ -295,7 +295,8 @@ an error message, and stop.
|
||||||
* OpenSSL::
|
* OpenSSL::
|
||||||
* zlib::
|
* zlib::
|
||||||
* lzo::
|
* lzo::
|
||||||
* libevent::
|
* libcurses::
|
||||||
|
* libreadline::
|
||||||
|
|
||||||
|
|
||||||
File: tinc.info, Node: OpenSSL, Next: zlib, Up: Libraries
|
File: tinc.info, Node: OpenSSL, Next: zlib, Up: Libraries
|
||||||
|
@ -307,8 +308,8 @@ For all cryptography-related functions, tinc uses the functions provided
|
||||||
by the OpenSSL library.
|
by the OpenSSL library.
|
||||||
|
|
||||||
If this library is not installed, you wil get an error when
|
If this library is not installed, you wil get an error when
|
||||||
configuring tinc for build. Support for running tinc without having
|
configuring tinc for build. Support for running tinc with other
|
||||||
OpenSSL installed _may_ be added in the future.
|
cryptographic libraries installed _may_ be added in the future.
|
||||||
|
|
||||||
You can use your operating system's package manager to install this
|
You can use your operating system's package manager to install this
|
||||||
if available. Make sure you install the development AND runtime
|
if available. Make sure you install the development AND runtime
|
||||||
|
@ -363,9 +364,12 @@ File: tinc.info, Node: zlib, Next: lzo, Prev: OpenSSL, Up: Libraries
|
||||||
For the optional compression of UDP packets, tinc uses the functions
|
For the optional compression of UDP packets, tinc uses the functions
|
||||||
provided by the zlib library.
|
provided by the zlib library.
|
||||||
|
|
||||||
If this library is not installed, you wil get an error when
|
If this library is not installed, you wil get an error when running
|
||||||
configuring tinc for build. Support for running tinc without having
|
the configure script. You can either install the zlib library, or
|
||||||
zlib installed _may_ be added in the future.
|
disable support for zlib compression by using the "-disable-zlib"
|
||||||
|
option when running the configure script. Note that if you disable
|
||||||
|
support for zlib, the resulting binary will not work correctly on VPNs
|
||||||
|
where zlib compression is used.
|
||||||
|
|
||||||
You can use your operating system's package manager to install this
|
You can use your operating system's package manager to install this
|
||||||
if available. Make sure you install the development AND runtime
|
if available. Make sure you install the development AND runtime
|
||||||
|
@ -378,16 +382,19 @@ make sure you build development and runtime libraries (which is the
|
||||||
default).
|
default).
|
||||||
|
|
||||||
|
|
||||||
File: tinc.info, Node: lzo, Next: libevent, Prev: zlib, Up: Libraries
|
File: tinc.info, Node: lzo, Next: libcurses, Prev: zlib, Up: Libraries
|
||||||
|
|
||||||
2.2.3 lzo
|
2.2.3 lzo
|
||||||
---------
|
---------
|
||||||
|
|
||||||
Another form of compression is offered using the lzo library.
|
Another form of compression is offered using the LZO library.
|
||||||
|
|
||||||
If this library is not installed, you wil get an error when
|
If this library is not installed, you wil get an error when running
|
||||||
configuring tinc for build. Support for running tinc without having lzo
|
the configure script. You can either install the LZO library, or
|
||||||
installed _may_ be added in the future.
|
disable support for LZO compression by using the "-disable-lzo" option
|
||||||
|
when running the configure script. Note that if you disable support for
|
||||||
|
LZO, the resulting binary will not work correctly on VPNs where LZO
|
||||||
|
compression is used.
|
||||||
|
|
||||||
You can use your operating system's package manager to install this
|
You can use your operating system's package manager to install this
|
||||||
if available. Make sure you install the development AND runtime
|
if available. Make sure you install the development AND runtime
|
||||||
|
@ -400,24 +407,52 @@ package. Please make sure you build development and runtime libraries
|
||||||
(which is the default).
|
(which is the default).
|
||||||
|
|
||||||
|
|
||||||
File: tinc.info, Node: libevent, Prev: lzo, Up: Libraries
|
File: tinc.info, Node: libcurses, Next: libreadline, Prev: lzo, Up: Libraries
|
||||||
|
|
||||||
2.2.4 libevent
|
2.2.4 libcurses
|
||||||
--------------
|
---------------
|
||||||
|
|
||||||
For the main event loop, tinc uses the libevent library.
|
For the "tincctl top" command, tinc requires a curses library.
|
||||||
|
|
||||||
If this library is not installed, you wil get an error when
|
If this library is not installed, you wil get an error when running
|
||||||
configuring tinc for build.
|
the configure script. You can either install a suitable curses
|
||||||
|
library, or disable all functionality that depends on a curses library
|
||||||
|
by using the "-disable-curses" option when running the configure script.
|
||||||
|
|
||||||
|
There are several curses libraries. It is recommended that you
|
||||||
|
install "ncurses" (`http://invisible-island.net/ncurses/'), however
|
||||||
|
other curses libraries should also work. In particular, "PDCurses"
|
||||||
|
(`http://pdcurses.sourceforge.net/') is recommended if you want to
|
||||||
|
compile tinc for Windows.
|
||||||
|
|
||||||
|
You can use your operating system's package manager to install this
|
||||||
|
if available. Make sure you install the development AND runtime versions
|
||||||
|
of this package.
|
||||||
|
|
||||||
|
|
||||||
|
File: tinc.info, Node: libreadline, Prev: libcurses, Up: Libraries
|
||||||
|
|
||||||
|
2.2.5 libreadline
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
For the "tincctl" command's shell functionality, tinc uses the readline
|
||||||
|
library.
|
||||||
|
|
||||||
|
If this library is not installed, you wil get an error when running
|
||||||
|
the configure script. You can either install a suitable readline
|
||||||
|
library, or disable all functionality that depends on a readline
|
||||||
|
library by using the "-disable-readline" option when running the
|
||||||
|
configure script.
|
||||||
|
|
||||||
You can use your operating system's package manager to install this
|
You can use your operating system's package manager to install this
|
||||||
if available. Make sure you install the development AND runtime
|
if available. Make sure you install the development AND runtime
|
||||||
versions of this package.
|
versions of this package.
|
||||||
|
|
||||||
If you have to install libevent manually, you can get the source code
|
If you have to install libreadline manually, you can get the source
|
||||||
from `http://libevent.org/'. Instructions on how to configure, build
|
code from `http://www.gnu.org/software/readline/'. Instructions on how
|
||||||
and install this package are included within the package. Please make
|
to configure, build and install this package are included within the
|
||||||
sure you build development and runtime libraries (which is the default).
|
package. Please make sure you build development and runtime libraries
|
||||||
|
(which is the default).
|
||||||
|
|
||||||
|
|
||||||
File: tinc.info, Node: Installation, Next: Configuration, Prev: Preparations, Up: Top
|
File: tinc.info, Node: Installation, Next: Configuration, Prev: Preparations, Up: Top
|
||||||
|
@ -738,6 +773,13 @@ AddressFamily = <ipv4|ipv6|any> (any)
|
||||||
system both IPv4 and IPv6 or just IPv6 listening sockets will be
|
system both IPv4 and IPv6 or just IPv6 listening sockets will be
|
||||||
created.
|
created.
|
||||||
|
|
||||||
|
AutoConnect = <count> (0) [experimental]
|
||||||
|
If set to a non-zero value, tinc will try to only have count meta
|
||||||
|
connections to other nodes, by automatically making or breaking
|
||||||
|
connections to known nodes. Higher values increase redundancy but
|
||||||
|
also increase meta data overhead. When using this option, a good
|
||||||
|
value is 3.
|
||||||
|
|
||||||
BindToAddress = <ADDRESS> [<PORT>]
|
BindToAddress = <ADDRESS> [<PORT>]
|
||||||
If your computer has more than one IPv4 or IPv6 address, tinc will
|
If your computer has more than one IPv4 or IPv6 address, tinc will
|
||||||
by default listen on all of them for incoming connections.
|
by default listen on all of them for incoming connections.
|
||||||
|
@ -912,14 +954,6 @@ Forwarding = <off|internal|kernel> (internal) [experimental]
|
||||||
efficient, but allows the kernel to apply its routing and
|
efficient, but allows the kernel to apply its routing and
|
||||||
firewall rules on them, and can also help debugging.
|
firewall rules on them, and can also help debugging.
|
||||||
|
|
||||||
GraphDumpFile = <FILENAME>
|
|
||||||
If this option is present, tinc will dump the current network
|
|
||||||
graph to the file FILENAME every minute, unless there were no
|
|
||||||
changes to the graph. The file is in a format that can be read by
|
|
||||||
graphviz tools. If FILENAME starts with a pipe symbol |, then the
|
|
||||||
rest of the filename is interpreted as a shell command that is
|
|
||||||
executed, the graph is then sent to stdin.
|
|
||||||
|
|
||||||
Hostnames = <yes|no> (no)
|
Hostnames = <yes|no> (no)
|
||||||
This option selects whether IP addresses (both real and on the VPN)
|
This option selects whether IP addresses (both real and on the VPN)
|
||||||
should be resolved. Since DNS lookups are blocking, it might
|
should be resolved. Since DNS lookups are blocking, it might
|
||||||
|
@ -1026,9 +1060,6 @@ PrivateKeyFile = <PATH> (`/etc/tinc/NETNAME/rsa_key.priv')
|
||||||
generated by `tincctl generate-keys'. It must be a full path, not
|
generated by `tincctl generate-keys'. It must be a full path, not
|
||||||
a relative directory.
|
a relative directory.
|
||||||
|
|
||||||
Note that there must be exactly one of PrivateKey or PrivateKeyFile
|
|
||||||
specified in the configuration file.
|
|
||||||
|
|
||||||
ProcessPriority = <low|normal|high>
|
ProcessPriority = <low|normal|high>
|
||||||
When this option is used the priority of the tincd process will be
|
When this option is used the priority of the tincd process will be
|
||||||
adjusted. Increasing the priority may help to reduce latency and
|
adjusted. Increasing the priority may help to reduce latency and
|
||||||
|
@ -2073,8 +2104,9 @@ File: tinc.info, Node: tincctl commands, Next: tincctl examples, Prev: tincct
|
||||||
store the files, but will default to the configuration directory
|
store the files, but will default to the configuration directory
|
||||||
(you can use the -c or -n option).
|
(you can use the -c or -n option).
|
||||||
|
|
||||||
`dump nodes'
|
`dump [reachable] nodes'
|
||||||
Dump a list of all known nodes in the VPN.
|
Dump a list of all known nodes in the VPN. If the reachable
|
||||||
|
keyword is used, only lists reachable nodes.
|
||||||
|
|
||||||
`dump edges'
|
`dump edges'
|
||||||
Dump a list of all known connections in the VPN.
|
Dump a list of all known connections in the VPN.
|
||||||
|
@ -2792,14 +2824,16 @@ Concept Index
|
||||||
* ANS_KEY: The meta-protocol. (line 64)
|
* ANS_KEY: The meta-protocol. (line 64)
|
||||||
* authentication: Authentication protocol.
|
* authentication: Authentication protocol.
|
||||||
(line 6)
|
(line 6)
|
||||||
|
* AutoConnect: Main configuration variables.
|
||||||
|
(line 12)
|
||||||
* binary package: Building and installing tinc.
|
* binary package: Building and installing tinc.
|
||||||
(line 9)
|
(line 9)
|
||||||
* BindToAddress: Main configuration variables.
|
* BindToAddress: Main configuration variables.
|
||||||
(line 12)
|
(line 19)
|
||||||
* BindToInterface: Main configuration variables.
|
* BindToInterface: Main configuration variables.
|
||||||
(line 23)
|
(line 30)
|
||||||
* Broadcast: Main configuration variables.
|
* Broadcast: Main configuration variables.
|
||||||
(line 34)
|
(line 41)
|
||||||
* Cabal: Security. (line 6)
|
* Cabal: Security. (line 6)
|
||||||
* CHAL_REPLY: Authentication protocol.
|
* CHAL_REPLY: Authentication protocol.
|
||||||
(line 10)
|
(line 10)
|
||||||
|
@ -2818,29 +2852,29 @@ Concept Index
|
||||||
(line 24)
|
(line 24)
|
||||||
* connection: The connection. (line 6)
|
* connection: The connection. (line 6)
|
||||||
* ConnectTo: Main configuration variables.
|
* ConnectTo: Main configuration variables.
|
||||||
(line 54)
|
(line 61)
|
||||||
* daemon: Running tinc. (line 11)
|
* daemon: Running tinc. (line 11)
|
||||||
* data-protocol: The meta-connection. (line 18)
|
* data-protocol: The meta-connection. (line 18)
|
||||||
* debug level: Runtime options. (line 17)
|
* debug level: Runtime options. (line 17)
|
||||||
* debug levels: Debug levels. (line 6)
|
* debug levels: Debug levels. (line 6)
|
||||||
* DecrementTTL: Main configuration variables.
|
* DecrementTTL: Main configuration variables.
|
||||||
(line 65)
|
(line 72)
|
||||||
* DEL_EDGE: The meta-protocol. (line 47)
|
* DEL_EDGE: The meta-protocol. (line 47)
|
||||||
* DEL_SUBNET: The meta-protocol. (line 47)
|
* DEL_SUBNET: The meta-protocol. (line 47)
|
||||||
* DEVICE: Scripts. (line 55)
|
* DEVICE: Scripts. (line 55)
|
||||||
* Device: Main configuration variables.
|
* Device: Main configuration variables.
|
||||||
(line 74)
|
(line 81)
|
||||||
* device files: Device files. (line 6)
|
* device files: Device files. (line 6)
|
||||||
* DeviceType: Main configuration variables.
|
* DeviceType: Main configuration variables.
|
||||||
(line 81)
|
(line 88)
|
||||||
* Digest: Host configuration variables.
|
* Digest: Host configuration variables.
|
||||||
(line 29)
|
(line 29)
|
||||||
* DirectOnly: Main configuration variables.
|
* DirectOnly: Main configuration variables.
|
||||||
(line 146)
|
|
||||||
* dummy: Main configuration variables.
|
|
||||||
(line 88)
|
|
||||||
* ECDSAPrivateKeyFile: Main configuration variables.
|
|
||||||
(line 153)
|
(line 153)
|
||||||
|
* dummy: Main configuration variables.
|
||||||
|
(line 95)
|
||||||
|
* ECDSAPrivateKeyFile: Main configuration variables.
|
||||||
|
(line 160)
|
||||||
* encapsulating: The UDP tunnel. (line 30)
|
* encapsulating: The UDP tunnel. (line 30)
|
||||||
* encryption: Encryption of network packets.
|
* encryption: Encryption of network packets.
|
||||||
(line 6)
|
(line 6)
|
||||||
|
@ -2848,52 +2882,51 @@ Concept Index
|
||||||
* example: Example configuration.
|
* example: Example configuration.
|
||||||
(line 6)
|
(line 6)
|
||||||
* exec: Main configuration variables.
|
* exec: Main configuration variables.
|
||||||
(line 326)
|
(line 322)
|
||||||
* ExperimentalProtocol: Main configuration variables.
|
* ExperimentalProtocol: Main configuration variables.
|
||||||
(line 157)
|
(line 164)
|
||||||
* Forwarding: Main configuration variables.
|
* Forwarding: Main configuration variables.
|
||||||
(line 166)
|
(line 173)
|
||||||
* frame type: The UDP tunnel. (line 6)
|
* frame type: The UDP tunnel. (line 6)
|
||||||
* GraphDumpFile: Main configuration variables.
|
|
||||||
(line 186)
|
|
||||||
* Hostnames: Main configuration variables.
|
* Hostnames: Main configuration variables.
|
||||||
(line 194)
|
(line 193)
|
||||||
* http: Main configuration variables.
|
* http: Main configuration variables.
|
||||||
(line 323)
|
(line 319)
|
||||||
* hub: Main configuration variables.
|
* hub: Main configuration variables.
|
||||||
(line 247)
|
(line 246)
|
||||||
* ID: Authentication protocol.
|
* ID: Authentication protocol.
|
||||||
(line 10)
|
(line 10)
|
||||||
* IndirectData: Host configuration variables.
|
* IndirectData: Host configuration variables.
|
||||||
(line 34)
|
(line 34)
|
||||||
* INTERFACE: Scripts. (line 58)
|
* INTERFACE: Scripts. (line 58)
|
||||||
* Interface: Main configuration variables.
|
* Interface: Main configuration variables.
|
||||||
(line 205)
|
(line 204)
|
||||||
* IRC: Contact information. (line 9)
|
* IRC: Contact information. (line 9)
|
||||||
* KEY_CHANGED: The meta-protocol. (line 64)
|
* KEY_CHANGED: The meta-protocol. (line 64)
|
||||||
* KeyExpire: Main configuration variables.
|
* KeyExpire: Main configuration variables.
|
||||||
(line 252)
|
(line 251)
|
||||||
* libevent: libevent. (line 6)
|
* libcurses: libcurses. (line 6)
|
||||||
* libraries: Libraries. (line 6)
|
* libraries: Libraries. (line 6)
|
||||||
|
* libreadline: libreadline. (line 6)
|
||||||
* license: OpenSSL. (line 36)
|
* license: OpenSSL. (line 36)
|
||||||
* LocalDiscovery: Main configuration variables.
|
* LocalDiscovery: Main configuration variables.
|
||||||
(line 213)
|
(line 212)
|
||||||
* lzo: lzo. (line 6)
|
* lzo: lzo. (line 6)
|
||||||
* MACExpire: Main configuration variables.
|
* MACExpire: Main configuration variables.
|
||||||
(line 258)
|
(line 257)
|
||||||
* MACLength: Host configuration variables.
|
* MACLength: Host configuration variables.
|
||||||
(line 42)
|
(line 42)
|
||||||
* meta-protocol: The meta-connection. (line 18)
|
* meta-protocol: The meta-connection. (line 18)
|
||||||
* META_KEY: Authentication protocol.
|
* META_KEY: Authentication protocol.
|
||||||
(line 10)
|
(line 10)
|
||||||
* Mode: Main configuration variables.
|
* Mode: Main configuration variables.
|
||||||
(line 224)
|
(line 223)
|
||||||
* multicast: Main configuration variables.
|
* multicast: Main configuration variables.
|
||||||
(line 100)
|
(line 107)
|
||||||
* multiple networks: Multiple networks. (line 6)
|
* multiple networks: Multiple networks. (line 6)
|
||||||
* NAME: Scripts. (line 52)
|
* NAME: Scripts. (line 52)
|
||||||
* Name: Main configuration variables.
|
* Name: Main configuration variables.
|
||||||
(line 263)
|
(line 262)
|
||||||
* netmask: Network interfaces. (line 39)
|
* netmask: Network interfaces. (line 39)
|
||||||
* NETNAME <1>: tincctl environment variables.
|
* NETNAME <1>: tincctl environment variables.
|
||||||
(line 6)
|
(line 6)
|
||||||
|
@ -2908,9 +2941,9 @@ Concept Index
|
||||||
(line 67)
|
(line 67)
|
||||||
* PING: The meta-protocol. (line 89)
|
* PING: The meta-protocol. (line 89)
|
||||||
* PingInterval: Main configuration variables.
|
* PingInterval: Main configuration variables.
|
||||||
(line 274)
|
(line 273)
|
||||||
* PingTimeout: Main configuration variables.
|
* PingTimeout: Main configuration variables.
|
||||||
(line 278)
|
(line 277)
|
||||||
* platforms: Supported platforms. (line 6)
|
* platforms: Supported platforms. (line 6)
|
||||||
* PMTU: Host configuration variables.
|
* PMTU: Host configuration variables.
|
||||||
(line 47)
|
(line 47)
|
||||||
|
@ -2921,32 +2954,32 @@ Concept Index
|
||||||
(line 55)
|
(line 55)
|
||||||
* port numbers: Other files. (line 17)
|
* port numbers: Other files. (line 17)
|
||||||
* PriorityInheritance: Main configuration variables.
|
* PriorityInheritance: Main configuration variables.
|
||||||
(line 284)
|
(line 283)
|
||||||
* private: Virtual Private Networks.
|
* private: Virtual Private Networks.
|
||||||
(line 10)
|
(line 10)
|
||||||
* PrivateKey: Main configuration variables.
|
* PrivateKey: Main configuration variables.
|
||||||
(line 289)
|
(line 288)
|
||||||
* PrivateKeyFile: Main configuration variables.
|
* PrivateKeyFile: Main configuration variables.
|
||||||
(line 295)
|
(line 294)
|
||||||
* ProcessPriority: Main configuration variables.
|
* ProcessPriority: Main configuration variables.
|
||||||
(line 303)
|
(line 299)
|
||||||
* Proxy: Main configuration variables.
|
* Proxy: Main configuration variables.
|
||||||
(line 308)
|
(line 304)
|
||||||
* PublicKey: Host configuration variables.
|
* PublicKey: Host configuration variables.
|
||||||
(line 59)
|
(line 59)
|
||||||
* PublicKeyFile: Host configuration variables.
|
* PublicKeyFile: Host configuration variables.
|
||||||
(line 62)
|
(line 62)
|
||||||
* raw_socket: Main configuration variables.
|
* raw_socket: Main configuration variables.
|
||||||
(line 93)
|
(line 100)
|
||||||
* release: Supported platforms. (line 14)
|
* release: Supported platforms. (line 14)
|
||||||
* REMOTEADDRESS: Scripts. (line 67)
|
* REMOTEADDRESS: Scripts. (line 67)
|
||||||
* REMOTEPORT: Scripts. (line 70)
|
* REMOTEPORT: Scripts. (line 70)
|
||||||
* ReplayWindow: Main configuration variables.
|
* ReplayWindow: Main configuration variables.
|
||||||
(line 331)
|
(line 327)
|
||||||
* REQ_KEY: The meta-protocol. (line 64)
|
* REQ_KEY: The meta-protocol. (line 64)
|
||||||
* requirements: Libraries. (line 6)
|
* requirements: Libraries. (line 6)
|
||||||
* router: Main configuration variables.
|
* router: Main configuration variables.
|
||||||
(line 227)
|
(line 226)
|
||||||
* runtime options: Runtime options. (line 9)
|
* runtime options: Runtime options. (line 9)
|
||||||
* scalability: tinc. (line 19)
|
* scalability: tinc. (line 19)
|
||||||
* scripts: Scripts. (line 6)
|
* scripts: Scripts. (line 6)
|
||||||
|
@ -2954,17 +2987,17 @@ Concept Index
|
||||||
(line 18)
|
(line 18)
|
||||||
* signals: Signals. (line 6)
|
* signals: Signals. (line 6)
|
||||||
* socks4: Main configuration variables.
|
* socks4: Main configuration variables.
|
||||||
(line 312)
|
(line 308)
|
||||||
* socks5: Main configuration variables.
|
* socks5: Main configuration variables.
|
||||||
(line 317)
|
(line 313)
|
||||||
* StrictSubnets: Main configuration variables.
|
* StrictSubnets: Main configuration variables.
|
||||||
(line 342)
|
(line 338)
|
||||||
* SUBNET: Scripts. (line 74)
|
* SUBNET: Scripts. (line 74)
|
||||||
* Subnet: Host configuration variables.
|
* Subnet: Host configuration variables.
|
||||||
(line 74)
|
(line 74)
|
||||||
* SVPN: Security. (line 11)
|
* SVPN: Security. (line 11)
|
||||||
* switch: Main configuration variables.
|
* switch: Main configuration variables.
|
||||||
(line 236)
|
(line 235)
|
||||||
* TCP: The meta-connection. (line 10)
|
* TCP: The meta-connection. (line 10)
|
||||||
* TCPonly: Host configuration variables.
|
* TCPonly: Host configuration variables.
|
||||||
(line 103)
|
(line 103)
|
||||||
|
@ -2976,24 +3009,24 @@ Concept Index
|
||||||
* tincd: tinc. (line 14)
|
* tincd: tinc. (line 14)
|
||||||
* traditional VPNs: tinc. (line 19)
|
* traditional VPNs: tinc. (line 19)
|
||||||
* tunifhead: Main configuration variables.
|
* tunifhead: Main configuration variables.
|
||||||
(line 135)
|
(line 142)
|
||||||
* TunnelServer: Main configuration variables.
|
* TunnelServer: Main configuration variables.
|
||||||
(line 347)
|
(line 343)
|
||||||
* tunnohead: Main configuration variables.
|
* tunnohead: Main configuration variables.
|
||||||
(line 129)
|
(line 136)
|
||||||
* UDP <1>: Encryption of network packets.
|
* UDP <1>: Encryption of network packets.
|
||||||
(line 12)
|
(line 12)
|
||||||
* UDP: The UDP tunnel. (line 30)
|
* UDP: The UDP tunnel. (line 30)
|
||||||
* UDPRcvBuf: Main configuration variables.
|
* UDPRcvBuf: Main configuration variables.
|
||||||
(line 354)
|
(line 350)
|
||||||
* UDPSndBuf: Main configuration variables.
|
* UDPSndBuf: Main configuration variables.
|
||||||
(line 359)
|
(line 355)
|
||||||
* UML: Main configuration variables.
|
* UML: Main configuration variables.
|
||||||
(line 111)
|
(line 118)
|
||||||
* Universal tun/tap: Configuration of Linux kernels.
|
* Universal tun/tap: Configuration of Linux kernels.
|
||||||
(line 6)
|
(line 6)
|
||||||
* VDE: Main configuration variables.
|
* VDE: Main configuration variables.
|
||||||
(line 116)
|
(line 123)
|
||||||
* virtual: Virtual Private Networks.
|
* virtual: Virtual Private Networks.
|
||||||
(line 18)
|
(line 18)
|
||||||
* virtual network device: The UDP tunnel. (line 6)
|
* virtual network device: The UDP tunnel. (line 6)
|
||||||
|
@ -3021,57 +3054,58 @@ Node: Configuration of Solaris kernels8891
|
||||||
Node: Configuration of Darwin (MacOS/X) kernels9552
|
Node: Configuration of Darwin (MacOS/X) kernels9552
|
||||||
Node: Configuration of Windows10241
|
Node: Configuration of Windows10241
|
||||||
Node: Libraries10755
|
Node: Libraries10755
|
||||||
Node: OpenSSL11156
|
Node: OpenSSL11173
|
||||||
Node: zlib13432
|
Node: zlib13461
|
||||||
Node: lzo14261
|
Node: lzo14487
|
||||||
Node: libevent15065
|
Node: libcurses15485
|
||||||
Node: Installation15760
|
Node: libreadline16405
|
||||||
Node: Building and installing tinc16776
|
Node: Installation17353
|
||||||
Node: Darwin (MacOS/X) build environment17435
|
Node: Building and installing tinc18369
|
||||||
Node: Cygwin (Windows) build environment18002
|
Node: Darwin (MacOS/X) build environment19028
|
||||||
Node: MinGW (Windows) build environment18590
|
Node: Cygwin (Windows) build environment19595
|
||||||
Node: System files19114
|
Node: MinGW (Windows) build environment20183
|
||||||
Node: Device files19379
|
Node: System files20707
|
||||||
Node: Other files19795
|
Node: Device files20972
|
||||||
Node: Configuration20408
|
Node: Other files21388
|
||||||
Node: Configuration introduction20695
|
Node: Configuration22001
|
||||||
Node: Multiple networks22242
|
Node: Configuration introduction22288
|
||||||
Node: How connections work23622
|
Node: Multiple networks23835
|
||||||
Node: Configuration files26195
|
Node: How connections work25215
|
||||||
Node: Main configuration variables27728
|
Node: Configuration files27788
|
||||||
Node: Host configuration variables44334
|
Node: Main configuration variables29321
|
||||||
Node: Scripts49564
|
Node: Host configuration variables45731
|
||||||
Node: How to configure52243
|
Node: Scripts50961
|
||||||
Node: Network interfaces56861
|
Node: How to configure53640
|
||||||
Node: Example configuration59262
|
Node: Network interfaces58258
|
||||||
Node: Running tinc64414
|
Node: Example configuration60659
|
||||||
Node: Runtime options65007
|
Node: Running tinc65811
|
||||||
Node: Signals67711
|
Node: Runtime options66404
|
||||||
Node: Debug levels68561
|
Node: Signals69108
|
||||||
Node: Solving problems69497
|
Node: Debug levels69958
|
||||||
Node: Error messages70927
|
Node: Solving problems70894
|
||||||
Node: Sending bug reports75249
|
Node: Error messages72324
|
||||||
Node: Controlling tinc76201
|
Node: Sending bug reports76646
|
||||||
Node: tincctl runtime options76598
|
Node: Controlling tinc77598
|
||||||
Node: tincctl environment variables77297
|
Node: tincctl runtime options77995
|
||||||
Node: tincctl commands77641
|
Node: tincctl environment variables78694
|
||||||
Node: tincctl examples81866
|
Node: tincctl commands79038
|
||||||
Node: tincctl top82471
|
Node: tincctl examples83343
|
||||||
Node: Technical information84069
|
Node: tincctl top83948
|
||||||
Node: The connection84304
|
Node: Technical information85546
|
||||||
Node: The UDP tunnel84616
|
Node: The connection85781
|
||||||
Node: The meta-connection87677
|
Node: The UDP tunnel86093
|
||||||
Node: The meta-protocol89146
|
Node: The meta-connection89154
|
||||||
Node: Security94155
|
Node: The meta-protocol90623
|
||||||
Node: Authentication protocol95285
|
Node: Security95632
|
||||||
Node: Encryption of network packets100289
|
Node: Authentication protocol96762
|
||||||
Node: Security issues101662
|
Node: Encryption of network packets101766
|
||||||
Node: Platform specific information103279
|
Node: Security issues103139
|
||||||
Node: Interface configuration103507
|
Node: Platform specific information104756
|
||||||
Node: Routes105960
|
Node: Interface configuration104984
|
||||||
Node: About us107876
|
Node: Routes107437
|
||||||
Node: Contact information108051
|
Node: About us109353
|
||||||
Node: Authors108455
|
Node: Contact information109528
|
||||||
Node: Concept Index108860
|
Node: Authors109932
|
||||||
|
Node: Concept Index110337
|
||||||
|
|
||||||
End Tag Table
|
End Tag Table
|
||||||
|
|
|
@ -339,7 +339,8 @@ having them installed, configure will give you an error message, and stop.
|
||||||
* OpenSSL::
|
* OpenSSL::
|
||||||
* zlib::
|
* zlib::
|
||||||
* lzo::
|
* lzo::
|
||||||
* libevent::
|
* libcurses::
|
||||||
|
* libreadline::
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@ -352,7 +353,7 @@ For all cryptography-related functions, tinc uses the functions provided
|
||||||
by the OpenSSL library.
|
by the OpenSSL library.
|
||||||
|
|
||||||
If this library is not installed, you wil get an error when configuring
|
If this library is not installed, you wil get an error when configuring
|
||||||
tinc for build. Support for running tinc without having OpenSSL
|
tinc for build. Support for running tinc with other cryptographic libraries
|
||||||
installed @emph{may} be added in the future.
|
installed @emph{may} be added in the future.
|
||||||
|
|
||||||
You can use your operating system's package manager to install this if
|
You can use your operating system's package manager to install this if
|
||||||
|
@ -415,9 +416,11 @@ Markus F.X.J. Oberhumer
|
||||||
For the optional compression of UDP packets, tinc uses the functions provided
|
For the optional compression of UDP packets, tinc uses the functions provided
|
||||||
by the zlib library.
|
by the zlib library.
|
||||||
|
|
||||||
If this library is not installed, you wil get an error when configuring
|
If this library is not installed, you wil get an error when running the
|
||||||
tinc for build. Support for running tinc without having zlib
|
configure script. You can either install the zlib library, or disable support
|
||||||
installed @emph{may} be added in the future.
|
for zlib compression by using the "--disable-zlib" option when running the
|
||||||
|
configure script. Note that if you disable support for zlib, the resulting
|
||||||
|
binary will not work correctly on VPNs where zlib compression is used.
|
||||||
|
|
||||||
You can use your operating system's package manager to install this if
|
You can use your operating system's package manager to install this if
|
||||||
available. Make sure you install the development AND runtime versions
|
available. Make sure you install the development AND runtime versions
|
||||||
|
@ -435,11 +438,13 @@ default).
|
||||||
@subsection lzo
|
@subsection lzo
|
||||||
|
|
||||||
@cindex lzo
|
@cindex lzo
|
||||||
Another form of compression is offered using the lzo library.
|
Another form of compression is offered using the LZO library.
|
||||||
|
|
||||||
If this library is not installed, you wil get an error when configuring
|
If this library is not installed, you wil get an error when running the
|
||||||
tinc for build. Support for running tinc without having lzo
|
configure script. You can either install the LZO library, or disable support
|
||||||
installed @emph{may} be added in the future.
|
for LZO compression by using the "--disable-lzo" option when running the
|
||||||
|
configure script. Note that if you disable support for LZO, the resulting
|
||||||
|
binary will not work correctly on VPNs where LZO compression is used.
|
||||||
|
|
||||||
You can use your operating system's package manager to install this if
|
You can use your operating system's package manager to install this if
|
||||||
available. Make sure you install the development AND runtime versions
|
available. Make sure you install the development AND runtime versions
|
||||||
|
@ -453,24 +458,48 @@ default).
|
||||||
|
|
||||||
|
|
||||||
@c ==================================================================
|
@c ==================================================================
|
||||||
@node libevent
|
@node libcurses
|
||||||
@subsection libevent
|
@subsection libcurses
|
||||||
|
|
||||||
@cindex libevent
|
@cindex libcurses
|
||||||
For the main event loop, tinc uses the libevent library.
|
For the "tincctl top" command, tinc requires a curses library.
|
||||||
|
|
||||||
If this library is not installed, you wil get an error when configuring
|
If this library is not installed, you wil get an error when running the
|
||||||
tinc for build.
|
configure script. You can either install a suitable curses library, or disable
|
||||||
|
all functionality that depends on a curses library by using the
|
||||||
|
"--disable-curses" option when running the configure script.
|
||||||
|
|
||||||
|
There are several curses libraries. It is recommended that you install
|
||||||
|
"ncurses" (@url{http://invisible-island.net/ncurses/}),
|
||||||
|
however other curses libraries should also work.
|
||||||
|
In particular, "PDCurses" (@url{http://pdcurses.sourceforge.net/})
|
||||||
|
is recommended if you want to compile tinc for Windows.
|
||||||
|
|
||||||
|
You can use your operating system's package manager to install this if
|
||||||
|
available. Make sure you install the development AND runtime versions
|
||||||
|
of this package.
|
||||||
|
|
||||||
|
|
||||||
|
@c ==================================================================
|
||||||
|
@node libreadline
|
||||||
|
@subsection libreadline
|
||||||
|
|
||||||
|
@cindex libreadline
|
||||||
|
For the "tincctl" command's shell functionality, tinc uses the readline library.
|
||||||
|
|
||||||
|
If this library is not installed, you wil get an error when running the
|
||||||
|
configure script. You can either install a suitable readline library, or
|
||||||
|
disable all functionality that depends on a readline library by using the
|
||||||
|
"--disable-readline" option when running the configure script.
|
||||||
|
|
||||||
You can use your operating system's package manager to install this if
|
You can use your operating system's package manager to install this if
|
||||||
available. Make sure you install the development AND runtime versions
|
available. Make sure you install the development AND runtime versions
|
||||||
of this package.
|
of this package.
|
||||||
|
|
||||||
If you have to install libevent manually, you can get the source code
|
If you have to install libreadline manually, you can get the source code from
|
||||||
from @url{http://libevent.org/}. Instructions on how to configure,
|
@url{http://www.gnu.org/software/readline/}. Instructions on how to configure,
|
||||||
build and install this package are included within the package. Please
|
build and install this package are included within the package. Please make
|
||||||
make sure you build development and runtime libraries (which is the
|
sure you build development and runtime libraries (which is the default).
|
||||||
default).
|
|
||||||
|
|
||||||
|
|
||||||
@c
|
@c
|
||||||
|
@ -805,6 +834,14 @@ This option affects the address family of listening and outgoing sockets.
|
||||||
If any is selected, then depending on the operating system
|
If any is selected, then depending on the operating system
|
||||||
both IPv4 and IPv6 or just IPv6 listening sockets will be created.
|
both IPv4 and IPv6 or just IPv6 listening sockets will be created.
|
||||||
|
|
||||||
|
@cindex AutoConnect
|
||||||
|
@item AutoConnect = <count> (0) [experimental]
|
||||||
|
If set to a non-zero value,
|
||||||
|
tinc will try to only have count meta connections to other nodes,
|
||||||
|
by automatically making or breaking connections to known nodes.
|
||||||
|
Higher values increase redundancy but also increase meta data overhead.
|
||||||
|
When using this option, a good value is 3.
|
||||||
|
|
||||||
@cindex BindToAddress
|
@cindex BindToAddress
|
||||||
@item BindToAddress = <@var{address}> [<@var{port}>]
|
@item BindToAddress = <@var{address}> [<@var{port}>]
|
||||||
If your computer has more than one IPv4 or IPv6 address, tinc
|
If your computer has more than one IPv4 or IPv6 address, tinc
|
||||||
|
@ -990,16 +1027,6 @@ This is less efficient, but allows the kernel to apply its routing and firewall
|
||||||
and can also help debugging.
|
and can also help debugging.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@cindex GraphDumpFile
|
|
||||||
@item GraphDumpFile = <@var{filename}>
|
|
||||||
If this option is present,
|
|
||||||
tinc will dump the current network graph to the file @var{filename}
|
|
||||||
every minute, unless there were no changes to the graph.
|
|
||||||
The file is in a format that can be read by graphviz tools.
|
|
||||||
If @var{filename} starts with a pipe symbol |,
|
|
||||||
then the rest of the filename is interpreted as a shell command
|
|
||||||
that is executed, the graph is then sent to stdin.
|
|
||||||
|
|
||||||
@cindex Hostnames
|
@cindex Hostnames
|
||||||
@item Hostnames = <yes|no> (no)
|
@item Hostnames = <yes|no> (no)
|
||||||
This option selects whether IP addresses (both real and on the VPN)
|
This option selects whether IP addresses (both real and on the VPN)
|
||||||
|
@ -1106,10 +1133,6 @@ This is the full path name of the RSA private key file that was
|
||||||
generated by @samp{tincctl generate-keys}. It must be a full path, not a
|
generated by @samp{tincctl generate-keys}. It must be a full path, not a
|
||||||
relative directory.
|
relative directory.
|
||||||
|
|
||||||
Note that there must be exactly one of PrivateKey
|
|
||||||
or PrivateKeyFile
|
|
||||||
specified in the configuration file.
|
|
||||||
|
|
||||||
@cindex ProcessPriority
|
@cindex ProcessPriority
|
||||||
@item ProcessPriority = <low|normal|high>
|
@item ProcessPriority = <low|normal|high>
|
||||||
When this option is used the priority of the tincd process will be adjusted.
|
When this option is used the priority of the tincd process will be adjusted.
|
||||||
|
@ -2199,8 +2222,9 @@ Generate public/private keypair of @var{bits} length. If @var{bits} is not speci
|
||||||
but will default to the configuration directory (you can use the -c or -n
|
but will default to the configuration directory (you can use the -c or -n
|
||||||
option).
|
option).
|
||||||
|
|
||||||
@item dump nodes
|
@item dump [reachable] nodes
|
||||||
Dump a list of all known nodes in the VPN.
|
Dump a list of all known nodes in the VPN.
|
||||||
|
If the reachable keyword is used, only lists reachable nodes.
|
||||||
|
|
||||||
@item dump edges
|
@item dump edges
|
||||||
Dump a list of all known connections in the VPN.
|
Dump a list of all known connections in the VPN.
|
||||||
|
|
|
@ -45,7 +45,6 @@ If no netname is specified on the command line with the
|
||||||
option, the value of this environment variable is used.
|
option, the value of this environment variable is used.
|
||||||
.El
|
.El
|
||||||
.Sh COMMANDS
|
.Sh COMMANDS
|
||||||
.zZ
|
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
.It init Op Ar name
|
.It init Op Ar name
|
||||||
Create initial configuration files and RSA and ECDSA keypairs with default length.
|
Create initial configuration files and RSA and ECDSA keypairs with default length.
|
||||||
|
@ -115,9 +114,9 @@ If
|
||||||
is omitted, the default length will be 2048 bits.
|
is omitted, the default length will be 2048 bits.
|
||||||
When saving keys to existing files, tinc will not delete the old keys;
|
When saving keys to existing files, tinc will not delete the old keys;
|
||||||
you have to remove them manually.
|
you have to remove them manually.
|
||||||
|
.It dump [reachable] nodes
|
||||||
.It dump nodes
|
|
||||||
Dump a list of all known nodes in the VPN.
|
Dump a list of all known nodes in the VPN.
|
||||||
|
If the keyword reachable is used, only lists reachable nodes.
|
||||||
.It dump edges
|
.It dump edges
|
||||||
Dump a list of all known connections in the VPN.
|
Dump a list of all known connections in the VPN.
|
||||||
.It dump subnets
|
.It dump subnets
|
||||||
|
@ -190,6 +189,7 @@ tincctl -n vpn config Subnet 192.168.1.0/24
|
||||||
tincctl -n vpn config bar.Address bar.example.com
|
tincctl -n vpn config bar.Address bar.example.com
|
||||||
tincctl -n vpn config ConnectTo bar
|
tincctl -n vpn config ConnectTo bar
|
||||||
tincctl -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@example.com
|
tincctl -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@example.com
|
||||||
|
.Ed
|
||||||
.Sh TOP
|
.Sh TOP
|
||||||
The top command connects to a running tinc daemon and repeatedly queries its per-node traffic counters.
|
The top command connects to a running tinc daemon and repeatedly queries its per-node traffic counters.
|
||||||
It displays a list of all the known nodes in the left-most column,
|
It displays a list of all the known nodes in the left-most column,
|
||||||
|
|
|
@ -56,10 +56,9 @@ DIST_COMMON = $(dist_bin_SCRIPTS) $(srcdir)/Makefile.am \
|
||||||
$(srcdir)/Makefile.in
|
$(srcdir)/Makefile.in
|
||||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||||
am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
|
am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
|
||||||
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libevent.m4 \
|
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/lzo.m4 \
|
||||||
$(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \
|
$(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \
|
||||||
$(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \
|
$(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.in
|
||||||
$(top_srcdir)/configure.in
|
|
||||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||||
$(ACLOCAL_M4)
|
$(ACLOCAL_M4)
|
||||||
mkinstalldirs = $(install_sh) -d
|
mkinstalldirs = $(install_sh) -d
|
||||||
|
|
4
have.h
4
have.h
|
@ -196,10 +196,6 @@
|
||||||
#include <netinet/if_ether.h>
|
#include <netinet/if_ether.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_EVENT_H
|
|
||||||
#include <event.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_MINGW
|
#ifdef HAVE_MINGW
|
||||||
#define SLASH "\\"
|
#define SLASH "\\"
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -54,10 +54,9 @@ subdir = m4
|
||||||
DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
||||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||||
am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
|
am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
|
||||||
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libevent.m4 \
|
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/lzo.m4 \
|
||||||
$(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \
|
$(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \
|
||||||
$(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \
|
$(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.in
|
||||||
$(top_srcdir)/configure.in
|
|
||||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||||
$(ACLOCAL_M4)
|
$(ACLOCAL_M4)
|
||||||
mkinstalldirs = $(install_sh) -d
|
mkinstalldirs = $(install_sh) -d
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
dnl Check to find the libevent headers/libraries
|
|
||||||
|
|
||||||
AC_DEFUN([tinc_LIBEVENT],
|
|
||||||
[
|
|
||||||
AC_ARG_WITH(libevent,
|
|
||||||
AS_HELP_STRING([--with-libevent=DIR], [libevent base directory, or:]),
|
|
||||||
[libevent="$withval"
|
|
||||||
CPPFLAGS="$CPPFLAGS -I$withval/include"
|
|
||||||
LDFLAGS="$LDFLAGS -L$withval/lib"]
|
|
||||||
)
|
|
||||||
|
|
||||||
AC_ARG_WITH(libevent-include,
|
|
||||||
AS_HELP_STRING([--with-libevent-include=DIR], [libevent headers directory]),
|
|
||||||
[libevent_include="$withval"
|
|
||||||
CPPFLAGS="$CPPFLAGS -I$withval"]
|
|
||||||
)
|
|
||||||
|
|
||||||
AC_ARG_WITH(libevent-lib,
|
|
||||||
AS_HELP_STRING([--with-libevent-lib=DIR], [libevent library directory]),
|
|
||||||
[libevent_lib="$withval"
|
|
||||||
LDFLAGS="$LDFLAGS -L$withval"]
|
|
||||||
)
|
|
||||||
|
|
||||||
AC_CHECK_HEADERS(event.h,
|
|
||||||
[],
|
|
||||||
[AC_MSG_ERROR("libevent header files not found."); break]
|
|
||||||
)
|
|
||||||
|
|
||||||
AC_CHECK_LIB(event, event_init,
|
|
||||||
[LIBS="-levent $LIBS"],
|
|
||||||
[AC_MSG_ERROR("libevent libraries not found.")]
|
|
||||||
)
|
|
||||||
])
|
|
|
@ -8,7 +8,7 @@ tincd_SOURCES = \
|
||||||
utils.c getopt.c getopt1.c list.c splay_tree.c dropin.c fake-getaddrinfo.c fake-getnameinfo.c hash.c \
|
utils.c getopt.c getopt1.c list.c splay_tree.c dropin.c fake-getaddrinfo.c fake-getnameinfo.c hash.c \
|
||||||
buffer.c conf.c connection.c control.c edge.c graph.c logger.c meta.c net.c net_packet.c net_setup.c \
|
buffer.c conf.c connection.c control.c edge.c graph.c logger.c meta.c net.c net_packet.c net_setup.c \
|
||||||
net_socket.c netutl.c node.c process.c protocol.c protocol_auth.c protocol_edge.c protocol_misc.c \
|
net_socket.c netutl.c node.c process.c protocol.c protocol_auth.c protocol_edge.c protocol_misc.c \
|
||||||
protocol_key.c protocol_subnet.c route.c sptps.c subnet.c subnet_parse.c tincd.c \
|
protocol_key.c protocol_subnet.c route.c sptps.c subnet.c subnet_parse.c event.c tincd.c \
|
||||||
dummy_device.c raw_socket_device.c multicast_device.c
|
dummy_device.c raw_socket_device.c multicast_device.c
|
||||||
|
|
||||||
if UML
|
if UML
|
||||||
|
@ -46,7 +46,7 @@ INCLUDES = @INCLUDES@ -I$(top_builddir)
|
||||||
noinst_HEADERS = \
|
noinst_HEADERS = \
|
||||||
xalloc.h utils.h getopt.h list.h splay_tree.h dropin.h fake-getaddrinfo.h fake-getnameinfo.h fake-gai-errnos.h ipv6.h ipv4.h ethernet.h \
|
xalloc.h utils.h getopt.h list.h splay_tree.h dropin.h fake-getaddrinfo.h fake-getnameinfo.h fake-gai-errnos.h ipv6.h ipv4.h ethernet.h \
|
||||||
buffer.h conf.h connection.h control.h control_common.h device.h edge.h graph.h info.h logger.h meta.h net.h netutl.h node.h process.h \
|
buffer.h conf.h connection.h control.h control_common.h device.h edge.h graph.h info.h logger.h meta.h net.h netutl.h node.h process.h \
|
||||||
protocol.h route.h subnet.h sptps.h tincctl.h top.h bsd/tunemu.h hash.h
|
protocol.h route.h subnet.h sptps.h tincctl.h top.h bsd/tunemu.h hash.h event.h
|
||||||
|
|
||||||
nodist_noinst_HEADERS = \
|
nodist_noinst_HEADERS = \
|
||||||
cipher.h crypto.h ecdh.h ecdsa.h digest.h prf.h rsa.h ecdsagen.h rsagen.h
|
cipher.h crypto.h ecdh.h ecdsa.h digest.h prf.h rsa.h ecdsagen.h rsagen.h
|
||||||
|
|
|
@ -62,10 +62,9 @@ DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
|
||||||
$(srcdir)/Makefile.in
|
$(srcdir)/Makefile.in
|
||||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||||
am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
|
am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
|
||||||
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libevent.m4 \
|
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/lzo.m4 \
|
||||||
$(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \
|
$(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \
|
||||||
$(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \
|
$(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.in
|
||||||
$(top_srcdir)/configure.in
|
|
||||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||||
$(ACLOCAL_M4)
|
$(ACLOCAL_M4)
|
||||||
mkinstalldirs = $(install_sh) -d
|
mkinstalldirs = $(install_sh) -d
|
||||||
|
@ -95,8 +94,8 @@ am__tincd_SOURCES_DIST = utils.c getopt.c getopt1.c list.c \
|
||||||
netutl.c node.c process.c protocol.c protocol_auth.c \
|
netutl.c node.c process.c protocol.c protocol_auth.c \
|
||||||
protocol_edge.c protocol_misc.c protocol_key.c \
|
protocol_edge.c protocol_misc.c protocol_key.c \
|
||||||
protocol_subnet.c route.c sptps.c subnet.c subnet_parse.c \
|
protocol_subnet.c route.c sptps.c subnet.c subnet_parse.c \
|
||||||
tincd.c dummy_device.c raw_socket_device.c multicast_device.c \
|
event.c tincd.c dummy_device.c raw_socket_device.c \
|
||||||
uml_device.c vde_device.c bsd/tunemu.c
|
multicast_device.c uml_device.c vde_device.c bsd/tunemu.c
|
||||||
@UML_TRUE@am__objects_1 = uml_device.$(OBJEXT)
|
@UML_TRUE@am__objects_1 = uml_device.$(OBJEXT)
|
||||||
@VDE_TRUE@am__objects_2 = vde_device.$(OBJEXT)
|
@VDE_TRUE@am__objects_2 = vde_device.$(OBJEXT)
|
||||||
@TUNEMU_TRUE@am__objects_3 = tunemu.$(OBJEXT)
|
@TUNEMU_TRUE@am__objects_3 = tunemu.$(OBJEXT)
|
||||||
|
@ -112,9 +111,10 @@ am_tincd_OBJECTS = utils.$(OBJEXT) getopt.$(OBJEXT) getopt1.$(OBJEXT) \
|
||||||
protocol_edge.$(OBJEXT) protocol_misc.$(OBJEXT) \
|
protocol_edge.$(OBJEXT) protocol_misc.$(OBJEXT) \
|
||||||
protocol_key.$(OBJEXT) protocol_subnet.$(OBJEXT) \
|
protocol_key.$(OBJEXT) protocol_subnet.$(OBJEXT) \
|
||||||
route.$(OBJEXT) sptps.$(OBJEXT) subnet.$(OBJEXT) \
|
route.$(OBJEXT) sptps.$(OBJEXT) subnet.$(OBJEXT) \
|
||||||
subnet_parse.$(OBJEXT) tincd.$(OBJEXT) dummy_device.$(OBJEXT) \
|
subnet_parse.$(OBJEXT) event.$(OBJEXT) tincd.$(OBJEXT) \
|
||||||
raw_socket_device.$(OBJEXT) multicast_device.$(OBJEXT) \
|
dummy_device.$(OBJEXT) raw_socket_device.$(OBJEXT) \
|
||||||
$(am__objects_1) $(am__objects_2) $(am__objects_3)
|
multicast_device.$(OBJEXT) $(am__objects_1) $(am__objects_2) \
|
||||||
|
$(am__objects_3)
|
||||||
nodist_tincd_OBJECTS = device.$(OBJEXT) cipher.$(OBJEXT) \
|
nodist_tincd_OBJECTS = device.$(OBJEXT) cipher.$(OBJEXT) \
|
||||||
crypto.$(OBJEXT) ecdh.$(OBJEXT) ecdsa.$(OBJEXT) \
|
crypto.$(OBJEXT) ecdh.$(OBJEXT) ecdsa.$(OBJEXT) \
|
||||||
digest.$(OBJEXT) prf.$(OBJEXT) rsa.$(OBJEXT)
|
digest.$(OBJEXT) prf.$(OBJEXT) rsa.$(OBJEXT)
|
||||||
|
@ -251,7 +251,7 @@ tincd_SOURCES = utils.c getopt.c getopt1.c list.c splay_tree.c \
|
||||||
net.c net_packet.c net_setup.c net_socket.c netutl.c node.c \
|
net.c net_packet.c net_setup.c net_socket.c netutl.c node.c \
|
||||||
process.c protocol.c protocol_auth.c protocol_edge.c \
|
process.c protocol.c protocol_auth.c protocol_edge.c \
|
||||||
protocol_misc.c protocol_key.c protocol_subnet.c route.c \
|
protocol_misc.c protocol_key.c protocol_subnet.c route.c \
|
||||||
sptps.c subnet.c subnet_parse.c tincd.c dummy_device.c \
|
sptps.c subnet.c subnet_parse.c event.c tincd.c dummy_device.c \
|
||||||
raw_socket_device.c multicast_device.c $(am__append_1) \
|
raw_socket_device.c multicast_device.c $(am__append_1) \
|
||||||
$(am__append_2) $(am__append_3)
|
$(am__append_2) $(am__append_3)
|
||||||
nodist_tincd_SOURCES = \
|
nodist_tincd_SOURCES = \
|
||||||
|
@ -273,7 +273,7 @@ DEFAULT_INCLUDES =
|
||||||
noinst_HEADERS = \
|
noinst_HEADERS = \
|
||||||
xalloc.h utils.h getopt.h list.h splay_tree.h dropin.h fake-getaddrinfo.h fake-getnameinfo.h fake-gai-errnos.h ipv6.h ipv4.h ethernet.h \
|
xalloc.h utils.h getopt.h list.h splay_tree.h dropin.h fake-getaddrinfo.h fake-getnameinfo.h fake-gai-errnos.h ipv6.h ipv4.h ethernet.h \
|
||||||
buffer.h conf.h connection.h control.h control_common.h device.h edge.h graph.h info.h logger.h meta.h net.h netutl.h node.h process.h \
|
buffer.h conf.h connection.h control.h control_common.h device.h edge.h graph.h info.h logger.h meta.h net.h netutl.h node.h process.h \
|
||||||
protocol.h route.h subnet.h sptps.h tincctl.h top.h bsd/tunemu.h hash.h
|
protocol.h route.h subnet.h sptps.h tincctl.h top.h bsd/tunemu.h hash.h event.h
|
||||||
|
|
||||||
nodist_noinst_HEADERS = \
|
nodist_noinst_HEADERS = \
|
||||||
cipher.h crypto.h ecdh.h ecdsa.h digest.h prf.h rsa.h ecdsagen.h rsagen.h
|
cipher.h crypto.h ecdh.h ecdsa.h digest.h prf.h rsa.h ecdsagen.h rsagen.h
|
||||||
|
@ -383,6 +383,7 @@ distclean-compile:
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecdsa.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecdsa.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecdsagen.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecdsagen.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edge.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edge.Po@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fake-getaddrinfo.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fake-getaddrinfo.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fake-getnameinfo.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fake-getnameinfo.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@
|
||||||
|
|
|
@ -68,11 +68,7 @@ void free_connection(connection_t *c) {
|
||||||
buffer_clear(&c->inbuf);
|
buffer_clear(&c->inbuf);
|
||||||
buffer_clear(&c->outbuf);
|
buffer_clear(&c->outbuf);
|
||||||
|
|
||||||
if(event_initialized(&c->inevent))
|
io_del(&c->io);
|
||||||
event_del(&c->inevent);
|
|
||||||
|
|
||||||
if(event_initialized(&c->outevent))
|
|
||||||
event_del(&c->outevent);
|
|
||||||
|
|
||||||
if(c->socket > 0)
|
if(c->socket > 0)
|
||||||
closesocket(c->socket);
|
closesocket(c->socket);
|
||||||
|
|
|
@ -90,8 +90,7 @@ typedef struct connection_t {
|
||||||
|
|
||||||
struct buffer_t inbuf;
|
struct buffer_t inbuf;
|
||||||
struct buffer_t outbuf;
|
struct buffer_t outbuf;
|
||||||
struct event inevent; /* input event on this metadata connection */
|
io_t io; /* input/output event on this metadata connection */
|
||||||
struct event outevent; /* output event on this metadata connection */
|
|
||||||
int tcplen; /* length of incoming TCPpacket */
|
int tcplen; /* length of incoming TCPpacket */
|
||||||
int allow_request; /* defined if there's only one request possible */
|
int allow_request; /* defined if there's only one request possible */
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ bool control_h(connection_t *c, const char *request) {
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case REQ_STOP:
|
case REQ_STOP:
|
||||||
event_loopexit(NULL);
|
event_exit();
|
||||||
return control_ok(c, REQ_STOP);
|
return control_ok(c, REQ_STOP);
|
||||||
|
|
||||||
case REQ_DUMP_NODES:
|
case REQ_DUMP_NODES:
|
||||||
|
@ -156,7 +156,7 @@ bool init_control(void) {
|
||||||
|
|
||||||
// Make sure we have a valid address, and map 0.0.0.0 and :: to 127.0.0.1 and ::1.
|
// Make sure we have a valid address, and map 0.0.0.0 and :: to 127.0.0.1 and ::1.
|
||||||
|
|
||||||
if(getsockname(listen_socket[0].tcp, (struct sockaddr *)&sa, &len)) {
|
if(getsockname(listen_socket[0].tcp.fd, (struct sockaddr *)&sa, &len)) {
|
||||||
xasprintf(&localhost, "127.0.0.1 port %d", myport);
|
xasprintf(&localhost, "127.0.0.1 port %d", myport);
|
||||||
} else {
|
} else {
|
||||||
if(sa.sa.sa_family == AF_INET) {
|
if(sa.sa.sa_family == AF_INET) {
|
||||||
|
|
18
src/dropin.h
18
src/dropin.h
|
@ -45,4 +45,22 @@ extern int gettimeofday(struct timeval *, void *);
|
||||||
extern int usleep(long long usec);
|
extern int usleep(long long usec);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef timeradd
|
||||||
|
#define timeradd(a, b, r) do {\
|
||||||
|
(r)->tv_sec = (a)->tv_sec + (b)->tv_sec;\
|
||||||
|
(r)->tv_usec = (a)->tv_usec + (b)->tv_usec;\
|
||||||
|
if((r)->tv_usec >= 1000000)\
|
||||||
|
(r)->tv_sec++, (r)->tv_usec -= 1000000;\
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef timersub
|
||||||
|
#define timersub(a, b, r) do {\
|
||||||
|
(r)->tv_sec = (a)->tv_sec - (b)->tv_sec;\
|
||||||
|
(r)->tv_usec = (a)->tv_usec - (b)->tv_usec;\
|
||||||
|
if((r)->tv_usec < 1000000)\
|
||||||
|
(r)->tv_sec--, (r)->tv_usec += 1000000;\
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __DROPIN_H__ */
|
#endif /* __DROPIN_H__ */
|
||||||
|
|
|
@ -41,6 +41,10 @@
|
||||||
#define ETH_P_IPV6 0x86DD
|
#define ETH_P_IPV6 0x86DD
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef ETH_P_8021Q
|
||||||
|
#define ETH_P_8021Q 0x8100
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_STRUCT_ETHER_HEADER
|
#ifndef HAVE_STRUCT_ETHER_HEADER
|
||||||
struct ether_header {
|
struct ether_header {
|
||||||
uint8_t ether_dhost[ETH_ALEN];
|
uint8_t ether_dhost[ETH_ALEN];
|
||||||
|
|
250
src/event.c
Normal file
250
src/event.c
Normal file
|
@ -0,0 +1,250 @@
|
||||||
|
/*
|
||||||
|
event.c -- I/O, timeout and signal event handling
|
||||||
|
Copyright (C) 2012 Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
#include "dropin.h"
|
||||||
|
#include "event.h"
|
||||||
|
#include "net.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
struct timeval now;
|
||||||
|
|
||||||
|
static fd_set readfds;
|
||||||
|
static fd_set writefds;
|
||||||
|
static volatile bool running;
|
||||||
|
|
||||||
|
static int io_compare(const io_t *a, const io_t *b) {
|
||||||
|
return a->fd - b->fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int timeout_compare(const timeout_t *a, const timeout_t *b) {
|
||||||
|
struct timeval diff;
|
||||||
|
timersub(&a->tv, &b->tv, &diff);
|
||||||
|
if(diff.tv_sec < 0)
|
||||||
|
return -1;
|
||||||
|
if(diff.tv_sec > 0)
|
||||||
|
return 1;
|
||||||
|
if(diff.tv_usec < 0)
|
||||||
|
return -1;
|
||||||
|
if(diff.tv_usec > 0)
|
||||||
|
return 1;
|
||||||
|
if(a < b)
|
||||||
|
return -1;
|
||||||
|
if(a > b)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int signal_compare(const signal_t *a, const signal_t *b) {
|
||||||
|
return a->signum - b->signum;
|
||||||
|
}
|
||||||
|
|
||||||
|
static splay_tree_t io_tree = {.compare = (splay_compare_t)io_compare};
|
||||||
|
static splay_tree_t timeout_tree = {.compare = (splay_compare_t)timeout_compare};
|
||||||
|
static splay_tree_t signal_tree = {.compare = (splay_compare_t)signal_compare};
|
||||||
|
|
||||||
|
void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags) {
|
||||||
|
if(io->cb)
|
||||||
|
return;
|
||||||
|
|
||||||
|
io->fd = fd;
|
||||||
|
io->cb = cb;
|
||||||
|
io->data = data;
|
||||||
|
io->node.data = io;
|
||||||
|
|
||||||
|
io_set(io, flags);
|
||||||
|
|
||||||
|
if(!splay_insert_node(&io_tree, &io->node))
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
void io_set(io_t *io, int flags) {
|
||||||
|
io->flags = flags;
|
||||||
|
|
||||||
|
if(flags & IO_READ)
|
||||||
|
FD_SET(io->fd, &readfds);
|
||||||
|
else
|
||||||
|
FD_CLR(io->fd, &readfds);
|
||||||
|
|
||||||
|
if(flags & IO_WRITE)
|
||||||
|
FD_SET(io->fd, &writefds);
|
||||||
|
else
|
||||||
|
FD_CLR(io->fd, &writefds);
|
||||||
|
}
|
||||||
|
|
||||||
|
void io_del(io_t *io) {
|
||||||
|
if(!io->cb)
|
||||||
|
return;
|
||||||
|
|
||||||
|
io_set(io, 0);
|
||||||
|
|
||||||
|
splay_unlink_node(&io_tree, &io->node);
|
||||||
|
io->cb = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void timeout_add(timeout_t *timeout, timeout_cb_t cb, void *data, struct timeval *tv) {
|
||||||
|
timeout->cb = cb;
|
||||||
|
timeout->data = data;
|
||||||
|
timeout->node.data = timeout;
|
||||||
|
|
||||||
|
timeout_set(timeout, tv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void timeout_set(timeout_t *timeout, struct timeval *tv) {
|
||||||
|
if(timerisset(&timeout->tv))
|
||||||
|
splay_unlink_node(&timeout_tree, &timeout->node);
|
||||||
|
|
||||||
|
if(!now.tv_sec)
|
||||||
|
gettimeofday(&now, NULL);
|
||||||
|
|
||||||
|
timeradd(&now, tv, &timeout->tv);
|
||||||
|
|
||||||
|
if(!splay_insert_node(&timeout_tree, &timeout->node))
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
void timeout_del(timeout_t *timeout) {
|
||||||
|
if(!timeout->cb)
|
||||||
|
return;
|
||||||
|
|
||||||
|
splay_unlink_node(&timeout_tree, &timeout->node);
|
||||||
|
timeout->cb = 0;
|
||||||
|
timeout->tv = (struct timeval){0, 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_MINGW
|
||||||
|
static io_t signalio;
|
||||||
|
static int pipefd[2] = {-1, -1};
|
||||||
|
|
||||||
|
static void signal_handler(int signum) {
|
||||||
|
unsigned char num = signum;
|
||||||
|
write(pipefd[1], &num, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void signalio_handler(void *data, int flags) {
|
||||||
|
unsigned char signum;
|
||||||
|
if(read(pipefd[0], &signum, 1) != 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
signal_t *sig = splay_search(&signal_tree, &((signal_t){.signum = signum}));
|
||||||
|
if(sig)
|
||||||
|
sig->cb(sig->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pipe_init(void) {
|
||||||
|
if(!pipe(pipefd))
|
||||||
|
io_add(&signalio, signalio_handler, NULL, pipefd[0], IO_READ);
|
||||||
|
}
|
||||||
|
|
||||||
|
void signal_add(signal_t *sig, signal_cb_t cb, void *data, int signum) {
|
||||||
|
if(sig->cb)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sig->cb = cb;
|
||||||
|
sig->data = data;
|
||||||
|
sig->signum = signum;
|
||||||
|
sig->node.data = sig;
|
||||||
|
|
||||||
|
if(pipefd[0] == -1)
|
||||||
|
pipe_init();
|
||||||
|
|
||||||
|
signal(sig->signum, signal_handler);
|
||||||
|
|
||||||
|
if(!splay_insert_node(&signal_tree, &sig->node))
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
void signal_del(signal_t *sig) {
|
||||||
|
if(!sig->cb)
|
||||||
|
return;
|
||||||
|
|
||||||
|
signal(sig->signum, SIG_DFL);
|
||||||
|
|
||||||
|
splay_unlink_node(&signal_tree, &sig->node);
|
||||||
|
sig->cb = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool event_loop(void) {
|
||||||
|
running = true;
|
||||||
|
|
||||||
|
fd_set readable;
|
||||||
|
fd_set writable;
|
||||||
|
|
||||||
|
while(running) {
|
||||||
|
gettimeofday(&now, NULL);
|
||||||
|
struct timeval diff, *tv = NULL;
|
||||||
|
|
||||||
|
while(timeout_tree.head) {
|
||||||
|
timeout_t *timeout = timeout_tree.head->data;
|
||||||
|
timersub(&timeout->tv, &now, &diff);
|
||||||
|
|
||||||
|
if(diff.tv_sec < 0) {
|
||||||
|
timeout->cb(timeout->data);
|
||||||
|
if(timercmp(&timeout->tv, &now, <))
|
||||||
|
timeout_del(timeout);
|
||||||
|
} else {
|
||||||
|
tv = &diff;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&readable, &readfds, sizeof readable);
|
||||||
|
memcpy(&writable, &writefds, sizeof writable);
|
||||||
|
|
||||||
|
int fds = 0;
|
||||||
|
|
||||||
|
if(io_tree.tail) {
|
||||||
|
io_t *last = io_tree.tail->data;
|
||||||
|
fds = last->fd + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_MINGW
|
||||||
|
LeaveCriticalSection(&mutex);
|
||||||
|
#endif
|
||||||
|
int n = select(fds, &readable, &writable, NULL, tv);
|
||||||
|
#ifdef HAVE_MINGW
|
||||||
|
EnterCriticalSection(&mutex);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(n < 0) {
|
||||||
|
if(sockwouldblock(errno))
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!n)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for splay_each(io_t, io, &io_tree) {
|
||||||
|
if(FD_ISSET(io->fd, &writable))
|
||||||
|
io->cb(io->data, IO_WRITE);
|
||||||
|
else if(FD_ISSET(io->fd, &readable))
|
||||||
|
io->cb(io->data, IO_READ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void event_exit(void) {
|
||||||
|
running = false;
|
||||||
|
}
|
70
src/event.h
Normal file
70
src/event.h
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
event.h -- I/O, timeout and signal event handling
|
||||||
|
Copyright (C) 2012 Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __TINC_EVENT_H__
|
||||||
|
#define __TINC_EVENT_H__
|
||||||
|
|
||||||
|
#include "splay_tree.h"
|
||||||
|
|
||||||
|
#define IO_READ 1
|
||||||
|
#define IO_WRITE 2
|
||||||
|
|
||||||
|
typedef void (*io_cb_t)(void *data, int flags);
|
||||||
|
typedef void (*timeout_cb_t)(void *data);
|
||||||
|
typedef void (*signal_cb_t)(void *data);
|
||||||
|
|
||||||
|
typedef struct io_t {
|
||||||
|
int fd;
|
||||||
|
int flags;
|
||||||
|
io_cb_t cb;
|
||||||
|
void *data;
|
||||||
|
splay_node_t node;
|
||||||
|
} io_t;
|
||||||
|
|
||||||
|
typedef struct timeout_t {
|
||||||
|
struct timeval tv;
|
||||||
|
timeout_cb_t cb;
|
||||||
|
void *data;
|
||||||
|
splay_node_t node;
|
||||||
|
} timeout_t;
|
||||||
|
|
||||||
|
typedef struct signal_t {
|
||||||
|
int signum;
|
||||||
|
signal_cb_t cb;
|
||||||
|
void *data;
|
||||||
|
splay_node_t node;
|
||||||
|
} signal_t;
|
||||||
|
|
||||||
|
extern struct timeval now;
|
||||||
|
|
||||||
|
extern void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags);
|
||||||
|
extern void io_del(io_t *io);
|
||||||
|
extern void io_set(io_t *io, int flags);
|
||||||
|
|
||||||
|
extern void timeout_add(timeout_t *timeout, timeout_cb_t cb, void *data, struct timeval *tv);
|
||||||
|
extern void timeout_del(timeout_t *timeout);
|
||||||
|
extern void timeout_set(timeout_t *timeout, struct timeval *tv);
|
||||||
|
|
||||||
|
extern void signal_add(signal_t *sig, signal_cb_t cb, void *data, int signum);
|
||||||
|
extern void signal_del(signal_t *sig);
|
||||||
|
|
||||||
|
extern bool event_loop(void);
|
||||||
|
extern void event_exit(void);
|
||||||
|
|
||||||
|
#endif
|
|
@ -213,8 +213,7 @@ static void check_reachability(void) {
|
||||||
n->minmtu = 0;
|
n->minmtu = 0;
|
||||||
n->mtuprobes = 0;
|
n->mtuprobes = 0;
|
||||||
|
|
||||||
if(timeout_initialized(&n->mtuevent))
|
timeout_del(&n->mtutimeout);
|
||||||
event_del(&n->mtuevent);
|
|
||||||
|
|
||||||
char *name;
|
char *name;
|
||||||
char *address;
|
char *address;
|
||||||
|
|
|
@ -55,7 +55,7 @@ hash_t *hash_alloc(size_t n, size_t size) {
|
||||||
hash_t *hash = xmalloc_and_zero(sizeof *hash);
|
hash_t *hash = xmalloc_and_zero(sizeof *hash);
|
||||||
hash->n = n;
|
hash->n = n;
|
||||||
hash->size = size;
|
hash->size = size;
|
||||||
hash->keys = xmalloc(hash->n * hash->size);
|
hash->keys = xmalloc_and_zero(hash->n * hash->size);
|
||||||
hash->values = xmalloc_and_zero(hash->n * sizeof *hash->values);
|
hash->values = xmalloc_and_zero(hash->n * sizeof *hash->values);
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
@ -100,6 +100,8 @@ void hash_clear(hash_t *hash) {
|
||||||
void hash_resize(hash_t *hash, size_t n) {
|
void hash_resize(hash_t *hash, size_t n) {
|
||||||
hash->keys = xrealloc(hash->keys, n * hash->size);
|
hash->keys = xrealloc(hash->keys, n * hash->size);
|
||||||
hash->values = xrealloc(hash->values, n * sizeof *hash->values);
|
hash->values = xrealloc(hash->values, n * sizeof *hash->values);
|
||||||
if(n > hash->n)
|
if(n > hash->n) {
|
||||||
|
memset(hash->keys + hash->n * hash->size, 0, (n - hash->n) * hash->size);
|
||||||
memset(hash->values + hash->n, 0, (n - hash->n) * sizeof *hash->values);
|
memset(hash->values + hash->n, 0, (n - hash->n) * sizeof *hash->values);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,6 @@ bool logcontrol = false;
|
||||||
|
|
||||||
static void real_logger(int level, int priority, const char *message) {
|
static void real_logger(int level, int priority, const char *message) {
|
||||||
char timestr[32] = "";
|
char timestr[32] = "";
|
||||||
time_t now;
|
|
||||||
static bool suppress = false;
|
static bool suppress = false;
|
||||||
|
|
||||||
// Bail out early if there is nothing to do.
|
// Bail out early if there is nothing to do.
|
||||||
|
@ -58,8 +57,10 @@ static void real_logger(int level, int priority, const char *message) {
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
break;
|
break;
|
||||||
case LOGMODE_FILE:
|
case LOGMODE_FILE:
|
||||||
now = time(NULL);
|
if(!now.tv_sec)
|
||||||
strftime(timestr, sizeof timestr, "%Y-%m-%d %H:%M:%S", localtime(&now));
|
gettimeofday(&now, NULL);
|
||||||
|
time_t now_sec = now.tv_sec;
|
||||||
|
strftime(timestr, sizeof timestr, "%Y-%m-%d %H:%M:%S", localtime(&now_sec));
|
||||||
fprintf(logfile, "%s %s[%ld]: %s\n", timestr, logident, (long)logpid, message);
|
fprintf(logfile, "%s %s[%ld]: %s\n", timestr, logident, (long)logpid, message);
|
||||||
fflush(logfile);
|
fflush(logfile);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -39,7 +39,7 @@ bool send_meta_sptps(void *handle, uint8_t type, const char *buffer, size_t leng
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer_add(&c->outbuf, buffer, length);
|
buffer_add(&c->outbuf, buffer, length);
|
||||||
event_add(&c->outevent, NULL);
|
io_set(&c->io, IO_READ | IO_WRITE);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -65,12 +65,11 @@ bool send_meta(connection_t *c, const char *buffer, int length) {
|
||||||
c->name, c->hostname);
|
c->name, c->hostname);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
buffer_add(&c->outbuf, buffer, length);
|
buffer_add(&c->outbuf, buffer, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
event_add(&c->outevent, NULL);
|
io_set(&c->io, IO_READ | IO_WRITE);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
175
src/net.c
175
src/net.c
|
@ -74,7 +74,7 @@ void purge(void) {
|
||||||
if(e->to == n)
|
if(e->to == n)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(!strictsubnets || !n->subnet_tree->head)
|
if(!autoconnect && (!strictsubnets || !n->subnet_tree->head))
|
||||||
/* in strictsubnets mode do not delete nodes with subnets */
|
/* in strictsubnets mode do not delete nodes with subnets */
|
||||||
node_del(n);
|
node_del(n);
|
||||||
}
|
}
|
||||||
|
@ -137,18 +137,16 @@ void terminate_connection(connection_t *c, bool report) {
|
||||||
end does not reply in time, we consider them dead
|
end does not reply in time, we consider them dead
|
||||||
and close the connection.
|
and close the connection.
|
||||||
*/
|
*/
|
||||||
static void timeout_handler(int fd, short events, void *event) {
|
static void timeout_handler(void *data) {
|
||||||
time_t now = time(NULL);
|
|
||||||
|
|
||||||
for list_each(connection_t, c, connection_list) {
|
for list_each(connection_t, c, connection_list) {
|
||||||
if(c->status.control)
|
if(c->status.control)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(c->last_ping_time + pingtimeout <= now) {
|
if(c->last_ping_time + pingtimeout <= now.tv_sec) {
|
||||||
if(c->status.active) {
|
if(c->status.active) {
|
||||||
if(c->status.pinged) {
|
if(c->status.pinged) {
|
||||||
logger(DEBUG_CONNECTIONS, LOG_INFO, "%s (%s) didn't respond to PING in %ld seconds", c->name, c->hostname, (long)now - c->last_ping_time);
|
logger(DEBUG_CONNECTIONS, LOG_INFO, "%s (%s) didn't respond to PING in %ld seconds", c->name, c->hostname, (long)now.tv_sec - c->last_ping_time);
|
||||||
} else if(c->last_ping_time + pinginterval <= now) {
|
} else if(c->last_ping_time + pinginterval <= now.tv_sec) {
|
||||||
send_ping(c);
|
send_ping(c);
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
|
@ -164,6 +162,15 @@ static void timeout_handler(int fd, short events, void *event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
timeout_set(data, &(struct timeval){pingtimeout, rand() % 100000});
|
||||||
|
}
|
||||||
|
|
||||||
|
static void periodic_handler(void *data) {
|
||||||
|
/* Check if there are too many contradicting ADD_EDGE and DEL_EDGE messages.
|
||||||
|
This usually only happens when another node has the same Name as this node.
|
||||||
|
If so, sleep for a short while to prevent a storm of contradicting messages.
|
||||||
|
*/
|
||||||
|
|
||||||
if(contradicting_del_edge > 100 && contradicting_add_edge > 100) {
|
if(contradicting_del_edge > 100 && contradicting_add_edge > 100) {
|
||||||
logger(DEBUG_ALWAYS, LOG_WARNING, "Possible node with same Name as us! Sleeping %d seconds.", sleeptime);
|
logger(DEBUG_ALWAYS, LOG_WARNING, "Possible node with same Name as us! Sleeping %d seconds.", sleeptime);
|
||||||
usleep(sleeptime * 1000000LL);
|
usleep(sleeptime * 1000000LL);
|
||||||
|
@ -179,11 +186,100 @@ static void timeout_handler(int fd, short events, void *event) {
|
||||||
contradicting_add_edge = 0;
|
contradicting_add_edge = 0;
|
||||||
contradicting_del_edge = 0;
|
contradicting_del_edge = 0;
|
||||||
|
|
||||||
event_add(event, &(struct timeval){pingtimeout, 0});
|
/* If AutoConnect is set, check if we need to make or break connections. */
|
||||||
|
|
||||||
|
if(autoconnect && node_tree->count > 1) {
|
||||||
|
/* Count number of active connections */
|
||||||
|
int nc = 0;
|
||||||
|
for list_each(connection_t, c, connection_list) {
|
||||||
|
if(c->status.active && !c->status.control)
|
||||||
|
nc++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(nc < autoconnect) {
|
||||||
|
/* Not enough active connections, try to add one.
|
||||||
|
Choose a random node, if we don't have a connection to it,
|
||||||
|
and we are not already trying to make one, create an
|
||||||
|
outgoing connection to this node.
|
||||||
|
*/
|
||||||
|
int r = rand() % node_tree->count;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for splay_each(node_t, n, node_tree) {
|
||||||
|
if(i++ != r)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(n->connection)
|
||||||
|
break;
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
for list_each(outgoing_t, outgoing, outgoing_list) {
|
||||||
|
if(!strcmp(outgoing->name, n->name)) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!found) {
|
||||||
|
logger(DEBUG_CONNECTIONS, LOG_INFO, "Autoconnecting to %s", n->name);
|
||||||
|
outgoing_t *outgoing = xmalloc_and_zero(sizeof *outgoing);
|
||||||
|
outgoing->name = xstrdup(n->name);
|
||||||
|
list_insert_tail(outgoing_list, outgoing);
|
||||||
|
setup_outgoing_connection(outgoing);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if(nc > autoconnect) {
|
||||||
|
/* Too many active connections, try to remove one.
|
||||||
|
Choose a random outgoing connection to a node
|
||||||
|
that has at least one other connection.
|
||||||
|
*/
|
||||||
|
int r = rand() % nc;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for list_each(connection_t, c, connection_list) {
|
||||||
|
if(!c->status.active || c->status.control)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(i++ != r)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(!c->outgoing || !c->node || c->node->edge_tree->count < 2)
|
||||||
|
break;
|
||||||
|
|
||||||
|
logger(DEBUG_CONNECTIONS, LOG_INFO, "Autodisconnecting from %s", c->name);
|
||||||
|
list_delete(outgoing_list, c->outgoing);
|
||||||
|
c->outgoing = NULL;
|
||||||
|
terminate_connection(c, c->status.active);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(nc >= autoconnect) {
|
||||||
|
/* If we have enough active connections,
|
||||||
|
remove any pending outgoing connections.
|
||||||
|
*/
|
||||||
|
for list_each(outgoing_t, o, outgoing_list) {
|
||||||
|
bool found = false;
|
||||||
|
for list_each(connection_t, c, connection_list) {
|
||||||
|
if(c->outgoing == o) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!found) {
|
||||||
|
logger(DEBUG_CONNECTIONS, LOG_INFO, "Cancelled outgoing connection to %s", o->name);
|
||||||
|
list_delete_node(outgoing_list, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
timeout_set(data, &(struct timeval){5, rand() % 100000});
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_meta_connection_data(int fd, short events, void *data) {
|
void handle_meta_connection_data(connection_t *c) {
|
||||||
connection_t *c = data;
|
|
||||||
int result;
|
int result;
|
||||||
socklen_t len = sizeof result;
|
socklen_t len = sizeof result;
|
||||||
|
|
||||||
|
@ -207,19 +303,19 @@ void handle_meta_connection_data(int fd, short events, void *data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sigterm_handler(int signal, short events, void *data) {
|
static void sigterm_handler(void *data) {
|
||||||
logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(signal));
|
logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum));
|
||||||
event_loopexit(NULL);
|
event_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sighup_handler(int signal, short events, void *data) {
|
static void sighup_handler(void *data) {
|
||||||
logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(signal));
|
logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum));
|
||||||
reopenlogger();
|
reopenlogger();
|
||||||
reload_configuration();
|
reload_configuration();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sigalrm_handler(int signal, short events, void *data) {
|
static void sigalrm_handler(void *data) {
|
||||||
logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(signal));
|
logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum));
|
||||||
retry();
|
retry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,7 +329,7 @@ int reload_configuration(void) {
|
||||||
|
|
||||||
if(!read_server_config()) {
|
if(!read_server_config()) {
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "Unable to reread configuration file, exitting.");
|
logger(DEBUG_ALWAYS, LOG_ERR, "Unable to reread configuration file, exitting.");
|
||||||
event_loopexit(NULL);
|
event_exit();
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,8 +428,7 @@ int reload_configuration(void) {
|
||||||
void retry(void) {
|
void retry(void) {
|
||||||
for list_each(connection_t, c, connection_list) {
|
for list_each(connection_t, c, connection_list) {
|
||||||
if(c->outgoing && !c->node) {
|
if(c->outgoing && !c->node) {
|
||||||
if(timeout_initialized(&c->outgoing->ev))
|
timeout_del(&c->outgoing->ev);
|
||||||
event_del(&c->outgoing->ev);
|
|
||||||
if(c->status.connecting)
|
if(c->status.connecting)
|
||||||
close(c->socket);
|
close(c->socket);
|
||||||
c->outgoing->timeout = 0;
|
c->outgoing->timeout = 0;
|
||||||
|
@ -346,40 +441,38 @@ void retry(void) {
|
||||||
this is where it all happens...
|
this is where it all happens...
|
||||||
*/
|
*/
|
||||||
int main_loop(void) {
|
int main_loop(void) {
|
||||||
struct event timeout_event;
|
timeout_t pingtimer = {{0}};
|
||||||
|
timeout_t periodictimer = {{0}};
|
||||||
|
|
||||||
timeout_set(&timeout_event, timeout_handler, &timeout_event);
|
timeout_add(&pingtimer, timeout_handler, &pingtimer, &(struct timeval){pingtimeout, rand() % 100000});
|
||||||
event_add(&timeout_event, &(struct timeval){pingtimeout, 0});
|
timeout_add(&periodictimer, periodic_handler, &periodictimer, &(struct timeval){pingtimeout, rand() % 100000});
|
||||||
|
|
||||||
#ifndef HAVE_MINGW
|
#ifndef HAVE_MINGW
|
||||||
struct event sighup_event;
|
signal_t sighup = {0};
|
||||||
struct event sigterm_event;
|
signal_t sigterm = {0};
|
||||||
struct event sigquit_event;
|
signal_t sigquit = {0};
|
||||||
struct event sigalrm_event;
|
signal_t sigalrm = {0};
|
||||||
|
|
||||||
signal_set(&sighup_event, SIGHUP, sighup_handler, NULL);
|
signal_add(&sighup, sighup_handler, &sighup, SIGHUP);
|
||||||
signal_add(&sighup_event, NULL);
|
signal_add(&sigterm, sigterm_handler, &sigterm, SIGTERM);
|
||||||
signal_set(&sigterm_event, SIGTERM, sigterm_handler, NULL);
|
signal_add(&sigquit, sigterm_handler, &sigquit, SIGQUIT);
|
||||||
signal_add(&sigterm_event, NULL);
|
signal_add(&sigalrm, sigalrm_handler, &sigalrm, SIGALRM);
|
||||||
signal_set(&sigquit_event, SIGQUIT, sigterm_handler, NULL);
|
|
||||||
signal_add(&sigquit_event, NULL);
|
|
||||||
signal_set(&sigalrm_event, SIGALRM, sigalrm_handler, NULL);
|
|
||||||
signal_add(&sigalrm_event, NULL);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(event_loop(0) < 0) {
|
if(!event_loop()) {
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error while waiting for input: %s", strerror(errno));
|
logger(DEBUG_ALWAYS, LOG_ERR, "Error while waiting for input: %s", strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef HAVE_MINGW
|
#ifndef HAVE_MINGW
|
||||||
signal_del(&sighup_event);
|
signal_del(&sighup);
|
||||||
signal_del(&sigterm_event);
|
signal_del(&sigalrm);
|
||||||
signal_del(&sigquit_event);
|
signal_del(&sigquit);
|
||||||
signal_del(&sigalrm_event);
|
signal_del(&sigterm);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
event_del(&timeout_event);
|
timeout_del(&periodictimer);
|
||||||
|
timeout_del(&pingtimer);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
19
src/net.h
19
src/net.h
|
@ -24,6 +24,7 @@
|
||||||
#include "ipv6.h"
|
#include "ipv6.h"
|
||||||
#include "cipher.h"
|
#include "cipher.h"
|
||||||
#include "digest.h"
|
#include "digest.h"
|
||||||
|
#include "event.h"
|
||||||
|
|
||||||
#ifdef ENABLE_JUMBOGRAMS
|
#ifdef ENABLE_JUMBOGRAMS
|
||||||
#define MTU 9018 /* 9000 bytes payload + 14 bytes ethernet header + 4 bytes VLAN tag */
|
#define MTU 9018 /* 9000 bytes payload + 14 bytes ethernet header + 4 bytes VLAN tag */
|
||||||
|
@ -99,10 +100,8 @@ typedef enum packet_type_t {
|
||||||
} packet_type_t;
|
} packet_type_t;
|
||||||
|
|
||||||
typedef struct listen_socket_t {
|
typedef struct listen_socket_t {
|
||||||
struct event ev_tcp;
|
io_t tcp;
|
||||||
struct event ev_udp;
|
io_t udp;
|
||||||
int tcp;
|
|
||||||
int udp;
|
|
||||||
sockaddr_t sa;
|
sockaddr_t sa;
|
||||||
} listen_socket_t;
|
} listen_socket_t;
|
||||||
|
|
||||||
|
@ -116,7 +115,7 @@ typedef struct outgoing_t {
|
||||||
struct config_t *cfg;
|
struct config_t *cfg;
|
||||||
struct addrinfo *ai;
|
struct addrinfo *ai;
|
||||||
struct addrinfo *aip;
|
struct addrinfo *aip;
|
||||||
struct event ev;
|
timeout_t ev;
|
||||||
} outgoing_t;
|
} outgoing_t;
|
||||||
|
|
||||||
extern list_t *outgoing_list;
|
extern list_t *outgoing_list;
|
||||||
|
@ -134,6 +133,7 @@ extern int udp_rcvbuf;
|
||||||
extern int udp_sndbuf;
|
extern int udp_sndbuf;
|
||||||
extern bool do_prune;
|
extern bool do_prune;
|
||||||
extern char *myport;
|
extern char *myport;
|
||||||
|
extern int autoconnect;
|
||||||
extern int contradicting_add_edge;
|
extern int contradicting_add_edge;
|
||||||
extern int contradicting_del_edge;
|
extern int contradicting_del_edge;
|
||||||
extern time_t last_config_check;
|
extern time_t last_config_check;
|
||||||
|
@ -160,10 +160,10 @@ extern char *scriptextension;
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
|
|
||||||
extern void retry_outgoing(outgoing_t *);
|
extern void retry_outgoing(outgoing_t *);
|
||||||
extern void handle_incoming_vpn_data(int, short, void *);
|
extern void handle_incoming_vpn_data(void *, int);
|
||||||
extern void finish_connecting(struct connection_t *);
|
extern void finish_connecting(struct connection_t *);
|
||||||
extern bool do_outgoing_connection(struct outgoing_t *);
|
extern bool do_outgoing_connection(struct outgoing_t *);
|
||||||
extern void handle_new_meta_connection(int, short, void *);
|
extern void handle_new_meta_connection(void *, int);
|
||||||
extern int setup_listen_socket(const sockaddr_t *);
|
extern int setup_listen_socket(const sockaddr_t *);
|
||||||
extern int setup_vpn_in_socket(const sockaddr_t *);
|
extern int setup_vpn_in_socket(const sockaddr_t *);
|
||||||
extern bool send_sptps_data(void *handle, uint8_t type, const char *data, size_t len);
|
extern bool send_sptps_data(void *handle, uint8_t type, const char *data, size_t len);
|
||||||
|
@ -183,13 +183,14 @@ extern bool node_read_ecdsa_public_key(struct node_t *);
|
||||||
extern bool read_ecdsa_public_key(struct connection_t *);
|
extern bool read_ecdsa_public_key(struct connection_t *);
|
||||||
extern bool read_rsa_public_key(struct connection_t *);
|
extern bool read_rsa_public_key(struct connection_t *);
|
||||||
extern void send_mtu_probe(struct node_t *);
|
extern void send_mtu_probe(struct node_t *);
|
||||||
extern void handle_device_data(int, short, void *);
|
extern void handle_device_data(void *, int);
|
||||||
extern void handle_meta_connection_data(int, short, void *);
|
extern void handle_meta_connection_data(struct connection_t *);
|
||||||
extern void regenerate_key(void);
|
extern void regenerate_key(void);
|
||||||
extern void purge(void);
|
extern void purge(void);
|
||||||
extern void retry(void);
|
extern void retry(void);
|
||||||
extern int reload_configuration(void);
|
extern int reload_configuration(void);
|
||||||
extern void load_all_subnets(void);
|
extern void load_all_subnets(void);
|
||||||
|
extern void load_all_nodes(void);
|
||||||
|
|
||||||
#ifndef HAVE_MINGW
|
#ifndef HAVE_MINGW
|
||||||
#define closesocket(s) close(s)
|
#define closesocket(s) close(s)
|
||||||
|
|
220
src/net_packet.c
220
src/net_packet.c
|
@ -77,7 +77,7 @@ bool localdiscovery = false;
|
||||||
which will be broadcast to the local network.
|
which will be broadcast to the local network.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void send_mtu_probe_handler(int fd, short events, void *data) {
|
static void send_mtu_probe_handler(void *data) {
|
||||||
node_t *n = data;
|
node_t *n = data;
|
||||||
int timeout = 1;
|
int timeout = 1;
|
||||||
|
|
||||||
|
@ -151,23 +151,37 @@ static void send_mtu_probe_handler(int fd, short events, void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
event_add(&n->mtuevent, &(struct timeval){timeout, 0});
|
timeout_set(&n->mtutimeout, &(struct timeval){timeout, rand() % 100000});
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_mtu_probe(node_t *n) {
|
void send_mtu_probe(node_t *n) {
|
||||||
if(!timeout_initialized(&n->mtuevent))
|
timeout_add(&n->mtutimeout, send_mtu_probe_handler, n, &(struct timeval){1, 0});
|
||||||
timeout_set(&n->mtuevent, send_mtu_probe_handler, n);
|
send_mtu_probe_handler(n);
|
||||||
send_mtu_probe_handler(0, 0, n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) {
|
static void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) {
|
||||||
logger(DEBUG_TRAFFIC, LOG_INFO, "Got MTU probe length %d from %s (%s)", packet->len, n->name, n->hostname);
|
logger(DEBUG_TRAFFIC, LOG_INFO, "Got MTU probe length %d from %s (%s)", packet->len, n->name, n->hostname);
|
||||||
|
|
||||||
if(!packet->data[0]) {
|
if(!packet->data[0]) {
|
||||||
|
/* It's a probe request, send back a reply */
|
||||||
|
|
||||||
packet->data[0] = 1;
|
packet->data[0] = 1;
|
||||||
send_udppacket(n, packet);
|
|
||||||
} else {
|
/* Temporarily set udp_confirmed, so that the reply is sent
|
||||||
|
back exactly the way it came in. */
|
||||||
|
|
||||||
|
bool udp_confirmed = n->status.udp_confirmed;
|
||||||
n->status.udp_confirmed = true;
|
n->status.udp_confirmed = true;
|
||||||
|
send_udppacket(n, packet);
|
||||||
|
n->status.udp_confirmed = udp_confirmed;
|
||||||
|
} else {
|
||||||
|
/* It's a valid reply: now we know bidirectional communication
|
||||||
|
is possible using the address and socket that the reply
|
||||||
|
packet used. */
|
||||||
|
|
||||||
|
n->status.udp_confirmed = true;
|
||||||
|
|
||||||
|
/* If we haven't established the PMTU yet, restart the discovery process. */
|
||||||
|
|
||||||
if(n->mtuprobes > 30) {
|
if(n->mtuprobes > 30) {
|
||||||
if(n->minmtu)
|
if(n->minmtu)
|
||||||
|
@ -176,6 +190,8 @@ static void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) {
|
||||||
n->mtuprobes = 1;
|
n->mtuprobes = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If applicable, raise the minimum supported MTU */
|
||||||
|
|
||||||
if(len > n->maxmtu)
|
if(len > n->maxmtu)
|
||||||
len = n->maxmtu;
|
len = n->maxmtu;
|
||||||
if(n->minmtu < len)
|
if(n->minmtu < len)
|
||||||
|
@ -438,6 +454,84 @@ static void send_sptps_packet(node_t *n, vpn_packet_t *origpkt) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void choose_udp_address(const node_t *n, const sockaddr_t **sa, int *sock) {
|
||||||
|
/* Latest guess */
|
||||||
|
*sa = &n->address;
|
||||||
|
*sock = n->sock;
|
||||||
|
|
||||||
|
/* If the UDP address is confirmed, use it. */
|
||||||
|
if(n->status.udp_confirmed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Send every third packet to n->address; that could be set
|
||||||
|
to the node's reflexive UDP address discovered during key
|
||||||
|
exchange. */
|
||||||
|
|
||||||
|
static int x = 0;
|
||||||
|
if(++x >= 3) {
|
||||||
|
x = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, address are found in edges to this node.
|
||||||
|
So we pick a random edge and a random socket. */
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
int j = rand() % n->edge_tree->count;
|
||||||
|
edge_t *candidate = NULL;
|
||||||
|
|
||||||
|
for splay_each(edge_t, e, n->edge_tree) {
|
||||||
|
if(i++ == j) {
|
||||||
|
candidate = e->reverse;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(candidate) {
|
||||||
|
*sa = &candidate->address;
|
||||||
|
*sock = rand() % listen_sockets;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure we have a suitable socket for the chosen address */
|
||||||
|
if(listen_socket[*sock].sa.sa.sa_family != (*sa)->sa.sa_family) {
|
||||||
|
for(int i = 0; i < listen_sockets; i++) {
|
||||||
|
if(listen_socket[i].sa.sa.sa_family == (*sa)->sa.sa_family) {
|
||||||
|
*sock = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void choose_broadcast_address(const node_t *n, const sockaddr_t **sa, int *sock) {
|
||||||
|
static sockaddr_t broadcast_ipv4 = {
|
||||||
|
.in = {
|
||||||
|
.sin_family = AF_INET,
|
||||||
|
.sin_addr.s_addr = -1,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static sockaddr_t broadcast_ipv6 = {
|
||||||
|
.in6 = {
|
||||||
|
.sin6_family = AF_INET6,
|
||||||
|
.sin6_addr.s6_addr[0x0] = 0xff,
|
||||||
|
.sin6_addr.s6_addr[0x1] = 0x02,
|
||||||
|
.sin6_addr.s6_addr[0xf] = 0x01,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
*sock = rand() % listen_sockets;
|
||||||
|
|
||||||
|
if(listen_socket[*sock].sa.sa.sa_family == AF_INET6) {
|
||||||
|
broadcast_ipv6.in6.sin6_port = n->prevedge->address.in.sin_port;
|
||||||
|
broadcast_ipv6.in6.sin6_scope_id = listen_socket[*sock].sa.in6.sin6_scope_id;
|
||||||
|
*sa = &broadcast_ipv6;
|
||||||
|
} else {
|
||||||
|
broadcast_ipv4.in.sin_port = n->prevedge->address.in.sin_port;
|
||||||
|
*sa = &broadcast_ipv4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
|
static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
|
||||||
vpn_packet_t pkt1, pkt2;
|
vpn_packet_t pkt1, pkt2;
|
||||||
vpn_packet_t *pkt[] = { &pkt1, &pkt2, &pkt1, &pkt2 };
|
vpn_packet_t *pkt[] = { &pkt1, &pkt2, &pkt1, &pkt2 };
|
||||||
|
@ -462,15 +556,13 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
|
||||||
/* Make sure we have a valid key */
|
/* Make sure we have a valid key */
|
||||||
|
|
||||||
if(!n->status.validkey) {
|
if(!n->status.validkey) {
|
||||||
time_t now = time(NULL);
|
|
||||||
|
|
||||||
logger(DEBUG_TRAFFIC, LOG_INFO,
|
logger(DEBUG_TRAFFIC, LOG_INFO,
|
||||||
"No valid key known yet for %s (%s), forwarding via TCP",
|
"No valid key known yet for %s (%s), forwarding via TCP",
|
||||||
n->name, n->hostname);
|
n->name, n->hostname);
|
||||||
|
|
||||||
if(n->last_req_key + 10 <= now) {
|
if(n->last_req_key + 10 <= now.tv_sec) {
|
||||||
send_req_key(n);
|
send_req_key(n);
|
||||||
n->last_req_key = now;
|
n->last_req_key = now.tv_sec;
|
||||||
}
|
}
|
||||||
|
|
||||||
send_tcppacket(n->nexthop->connection, origpkt);
|
send_tcppacket(n->nexthop->connection, origpkt);
|
||||||
|
@ -534,88 +626,27 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
|
||||||
|
|
||||||
/* Send the packet */
|
/* Send the packet */
|
||||||
|
|
||||||
sockaddr_t *sa;
|
const sockaddr_t *sa;
|
||||||
int sock;
|
int sock;
|
||||||
|
|
||||||
/* Overloaded use of priority field: -1 means local broadcast */
|
/* Overloaded use of priority field: -1 means local broadcast */
|
||||||
|
|
||||||
if(origpriority == -1 && n->prevedge) {
|
if(origpriority == -1 && n->prevedge)
|
||||||
sockaddr_t broadcast;
|
choose_broadcast_address(n, &sa, &sock);
|
||||||
broadcast.in.sin_family = AF_INET;
|
else
|
||||||
broadcast.in.sin_addr.s_addr = -1;
|
choose_udp_address(n, &sa, &sock);
|
||||||
broadcast.in.sin_port = n->prevedge->address.in.sin_port;
|
|
||||||
sa = &broadcast;
|
|
||||||
sock = 0;
|
|
||||||
} else {
|
|
||||||
if(origpriority == -1)
|
|
||||||
origpriority = 0;
|
|
||||||
|
|
||||||
if(n->status.udp_confirmed) {
|
|
||||||
/* Address of this node is confirmed, so use it. */
|
|
||||||
sa = &n->address;
|
|
||||||
sock = n->sock;
|
|
||||||
} else {
|
|
||||||
/* Otherwise, go through the list of known addresses of
|
|
||||||
this node. The first address we try is always the
|
|
||||||
one in n->address; that could be set to the node's
|
|
||||||
reflexive UDP address discovered during key
|
|
||||||
exchange. The other known addresses are those found
|
|
||||||
in edges to this node. */
|
|
||||||
|
|
||||||
static unsigned int i;
|
|
||||||
int j = 0;
|
|
||||||
edge_t *candidate = NULL;
|
|
||||||
|
|
||||||
if(i) {
|
|
||||||
for splay_each(edge_t, e, edge_weight_tree) {
|
|
||||||
if(e->to != n)
|
|
||||||
continue;
|
|
||||||
j++;
|
|
||||||
if(!candidate || j == i)
|
|
||||||
candidate = e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!candidate) {
|
|
||||||
sa = &n->address;
|
|
||||||
sock = n->sock;
|
|
||||||
} else {
|
|
||||||
sa = &candidate->address;
|
|
||||||
sock = rand() % listen_sockets;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(i++)
|
|
||||||
if(i > j)
|
|
||||||
i = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Determine which socket we have to use */
|
|
||||||
|
|
||||||
if(sa->sa.sa_family != listen_socket[sock].sa.sa.sa_family)
|
|
||||||
for(sock = 0; sock < listen_sockets; sock++)
|
|
||||||
if(sa->sa.sa_family == listen_socket[sock].sa.sa.sa_family)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if(sock >= listen_sockets)
|
|
||||||
sock = 0;
|
|
||||||
|
|
||||||
if(!n->status.udp_confirmed)
|
|
||||||
n->sock = sock;
|
|
||||||
|
|
||||||
#if defined(SOL_IP) && defined(IP_TOS)
|
#if defined(SOL_IP) && defined(IP_TOS)
|
||||||
if(priorityinheritance && origpriority != priority
|
if(priorityinheritance && origpriority != priority
|
||||||
&& listen_socket[n->sock].sa.sa.sa_family == AF_INET) {
|
&& listen_socket[n->sock].sa.sa.sa_family == AF_INET) {
|
||||||
priority = origpriority;
|
priority = origpriority;
|
||||||
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Setting outgoing packet priority to %d", priority);
|
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Setting outgoing packet priority to %d", priority);
|
||||||
if(setsockopt(listen_socket[n->sock].udp, SOL_IP, IP_TOS, &priority, sizeof(priority))) /* SO_PRIORITY doesn't seem to work */
|
if(setsockopt(listen_socket[n->sock].udp.fd, SOL_IP, IP_TOS, &priority, sizeof(priority))) /* SO_PRIORITY doesn't seem to work */
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setsockopt", strerror(errno));
|
logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setsockopt", strerror(errno));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
socklen_t sl = SALEN(n->address.sa);
|
if(sendto(listen_socket[sock].udp.fd, (char *) &inpkt->seqno, inpkt->len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) {
|
||||||
|
|
||||||
if(sendto(listen_socket[sock].udp, (char *) &inpkt->seqno, inpkt->len, 0, &sa->sa, sl) < 0 && !sockwouldblock(sockerrno)) {
|
|
||||||
if(sockmsgsize(sockerrno)) {
|
if(sockmsgsize(sockerrno)) {
|
||||||
if(n->maxmtu >= origlen)
|
if(n->maxmtu >= origlen)
|
||||||
n->maxmtu = origlen - 1;
|
n->maxmtu = origlen - 1;
|
||||||
|
@ -647,15 +678,12 @@ bool send_sptps_data(void *handle, uint8_t type, const char *data, size_t len) {
|
||||||
|
|
||||||
/* Otherwise, send the packet via UDP */
|
/* Otherwise, send the packet via UDP */
|
||||||
|
|
||||||
struct sockaddr *sa;
|
const sockaddr_t *sa;
|
||||||
socklen_t sl;
|
|
||||||
int sock;
|
int sock;
|
||||||
|
|
||||||
sa = &(to->address.sa);
|
choose_udp_address(to, &sa, &sock);
|
||||||
sl = SALEN(to->address.sa);
|
|
||||||
sock = to->sock;
|
|
||||||
|
|
||||||
if(sendto(listen_socket[sock].udp, data, len, 0, sa, sl) < 0 && !sockwouldblock(sockerrno)) {
|
if(sendto(listen_socket[sock].udp.fd, data, len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) {
|
||||||
if(sockmsgsize(sockerrno)) {
|
if(sockmsgsize(sockerrno)) {
|
||||||
if(to->maxmtu >= len)
|
if(to->maxmtu >= len)
|
||||||
to->maxmtu = len - 1;
|
to->maxmtu = len - 1;
|
||||||
|
@ -711,11 +739,11 @@ bool receive_sptps_record(void *handle, uint8_t type, const char *data, uint16_t
|
||||||
|
|
||||||
int offset = (type & PKT_MAC) ? 0 : 14;
|
int offset = (type & PKT_MAC) ? 0 : 14;
|
||||||
if(type & PKT_COMPRESSED) {
|
if(type & PKT_COMPRESSED) {
|
||||||
len = uncompress_packet(inpkt.data + offset, (const uint8_t *)data, len, from->incompression);
|
length_t ulen = uncompress_packet(inpkt.data + offset, (const uint8_t *)data, len, from->incompression);
|
||||||
if(len < 0) {
|
if(ulen < 0) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
inpkt.len = len + offset;
|
inpkt.len = ulen + offset;
|
||||||
}
|
}
|
||||||
if(inpkt.len > MAXSIZE)
|
if(inpkt.len > MAXSIZE)
|
||||||
abort();
|
abort();
|
||||||
|
@ -838,14 +866,13 @@ static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) {
|
||||||
node_t *n = NULL;
|
node_t *n = NULL;
|
||||||
bool hard = false;
|
bool hard = false;
|
||||||
static time_t last_hard_try = 0;
|
static time_t last_hard_try = 0;
|
||||||
time_t now = time(NULL);
|
|
||||||
|
|
||||||
for splay_each(edge_t, e, edge_weight_tree) {
|
for splay_each(edge_t, e, edge_weight_tree) {
|
||||||
if(!e->to->status.reachable || e->to == myself)
|
if(!e->to->status.reachable || e->to == myself)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(sockaddrcmp_noport(from, &e->address)) {
|
if(sockaddrcmp_noport(from, &e->address)) {
|
||||||
if(last_hard_try == now)
|
if(last_hard_try == now.tv_sec)
|
||||||
continue;
|
continue;
|
||||||
hard = true;
|
hard = true;
|
||||||
}
|
}
|
||||||
|
@ -858,13 +885,14 @@ static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(hard)
|
if(hard)
|
||||||
last_hard_try = now;
|
last_hard_try = now.tv_sec;
|
||||||
|
|
||||||
last_hard_try = now;
|
last_hard_try = now.tv_sec;
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_incoming_vpn_data(int sock, short events, void *data) {
|
void handle_incoming_vpn_data(void *data, int flags) {
|
||||||
|
listen_socket_t *ls = data;
|
||||||
vpn_packet_t pkt;
|
vpn_packet_t pkt;
|
||||||
char *hostname;
|
char *hostname;
|
||||||
sockaddr_t from = {{0}};
|
sockaddr_t from = {{0}};
|
||||||
|
@ -872,7 +900,7 @@ void handle_incoming_vpn_data(int sock, short events, void *data) {
|
||||||
node_t *n;
|
node_t *n;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
len = recvfrom(sock, (char *) &pkt.seqno, MAXSIZE, 0, &from.sa, &fromlen);
|
len = recvfrom(ls->udp.fd, (char *) &pkt.seqno, MAXSIZE, 0, &from.sa, &fromlen);
|
||||||
|
|
||||||
if(len <= 0 || len > MAXSIZE) {
|
if(len <= 0 || len > MAXSIZE) {
|
||||||
if(!sockwouldblock(sockerrno))
|
if(!sockwouldblock(sockerrno))
|
||||||
|
@ -900,12 +928,12 @@ void handle_incoming_vpn_data(int sock, short events, void *data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
n->sock = (intptr_t)data;
|
n->sock = ls - listen_socket;
|
||||||
|
|
||||||
receive_udppacket(n, &pkt);
|
receive_udppacket(n, &pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_device_data(int sock, short events, void *data) {
|
void handle_device_data(void *data, int flags) {
|
||||||
vpn_packet_t packet;
|
vpn_packet_t packet;
|
||||||
|
|
||||||
packet.priority = 0;
|
packet.priority = 0;
|
||||||
|
|
127
src/net_setup.c
127
src/net_setup.c
|
@ -42,7 +42,7 @@
|
||||||
#include "xalloc.h"
|
#include "xalloc.h"
|
||||||
|
|
||||||
char *myport;
|
char *myport;
|
||||||
static struct event device_ev;
|
static io_t device_io;
|
||||||
devops_t devops;
|
devops_t devops;
|
||||||
|
|
||||||
char *proxyhost;
|
char *proxyhost;
|
||||||
|
@ -50,6 +50,7 @@ char *proxyport;
|
||||||
char *proxyuser;
|
char *proxyuser;
|
||||||
char *proxypass;
|
char *proxypass;
|
||||||
proxytype_t proxytype;
|
proxytype_t proxytype;
|
||||||
|
int autoconnect;
|
||||||
|
|
||||||
char *scriptinterpreter;
|
char *scriptinterpreter;
|
||||||
char *scriptextension;
|
char *scriptextension;
|
||||||
|
@ -269,22 +270,16 @@ static bool read_rsa_private_key(void) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct event keyexpire_event;
|
static timeout_t keyexpire_timeout;
|
||||||
|
|
||||||
static void keyexpire_handler(int fd, short events, void *data) {
|
static void keyexpire_handler(void *data) {
|
||||||
regenerate_key();
|
regenerate_key();
|
||||||
|
timeout_set(data, &(struct timeval){keylifetime, rand() % 100000});
|
||||||
}
|
}
|
||||||
|
|
||||||
void regenerate_key(void) {
|
void regenerate_key(void) {
|
||||||
if(timeout_initialized(&keyexpire_event)) {
|
logger(DEBUG_STATUS, LOG_INFO, "Expiring symmetric keys");
|
||||||
logger(DEBUG_STATUS, LOG_INFO, "Expiring symmetric keys");
|
send_key_changed();
|
||||||
event_del(&keyexpire_event);
|
|
||||||
send_key_changed();
|
|
||||||
} else {
|
|
||||||
timeout_set(&keyexpire_event, keyexpire_handler, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
event_add(&keyexpire_event, &(struct timeval){keylifetime, 0});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -347,6 +342,36 @@ void load_all_subnets(void) {
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void load_all_nodes(void) {
|
||||||
|
DIR *dir;
|
||||||
|
struct dirent *ent;
|
||||||
|
char *dname;
|
||||||
|
|
||||||
|
xasprintf(&dname, "%s" SLASH "hosts", confbase);
|
||||||
|
dir = opendir(dname);
|
||||||
|
if(!dir) {
|
||||||
|
logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", dname, strerror(errno));
|
||||||
|
free(dname);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while((ent = readdir(dir))) {
|
||||||
|
if(!check_id(ent->d_name))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
node_t *n = lookup_node(ent->d_name);
|
||||||
|
if(n)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
n = new_node();
|
||||||
|
n->name = xstrdup(ent->d_name);
|
||||||
|
node_add(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
char *get_name(void) {
|
char *get_name(void) {
|
||||||
char *name = NULL;
|
char *name = NULL;
|
||||||
|
|
||||||
|
@ -362,7 +387,7 @@ char *get_name(void) {
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "Invalid Name: environment variable %s does not exist\n", name + 1);
|
logger(DEBUG_ALWAYS, LOG_ERR, "Invalid Name: environment variable %s does not exist\n", name + 1);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
envname = alloca(32);
|
char envname[32];
|
||||||
if(gethostname(envname, 32)) {
|
if(gethostname(envname, 32)) {
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "Could not get hostname: %s\n", strerror(errno));
|
logger(DEBUG_ALWAYS, LOG_ERR, "Could not get hostname: %s\n", strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
|
@ -570,6 +595,8 @@ bool setup_myself_reloadable(void) {
|
||||||
if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime))
|
if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime))
|
||||||
keylifetime = 3600;
|
keylifetime = 3600;
|
||||||
|
|
||||||
|
get_config_int(lookup_config(config_tree, "AutoConnect"), &autoconnect);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -683,7 +710,8 @@ static bool setup_myself(void) {
|
||||||
|
|
||||||
free(cipher);
|
free(cipher);
|
||||||
|
|
||||||
regenerate_key();
|
send_key_changed();
|
||||||
|
timeout_add(&keyexpire_timeout, keyexpire_handler, &keyexpire_timeout, &(struct timeval){keylifetime, rand() % 100000});
|
||||||
|
|
||||||
/* Check if we want to use message authentication codes... */
|
/* Check if we want to use message authentication codes... */
|
||||||
|
|
||||||
|
@ -730,6 +758,8 @@ static bool setup_myself(void) {
|
||||||
|
|
||||||
if(strictsubnets)
|
if(strictsubnets)
|
||||||
load_all_subnets();
|
load_all_subnets();
|
||||||
|
else if(autoconnect)
|
||||||
|
load_all_nodes();
|
||||||
|
|
||||||
/* Open device */
|
/* Open device */
|
||||||
|
|
||||||
|
@ -755,15 +785,8 @@ static bool setup_myself(void) {
|
||||||
if(!devops.setup())
|
if(!devops.setup())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(device_fd >= 0) {
|
if(device_fd >= 0)
|
||||||
event_set(&device_ev, device_fd, EV_READ|EV_PERSIST, handle_device_data, NULL);
|
io_add(&device_io, handle_device_data, NULL, device_fd, IO_READ);
|
||||||
|
|
||||||
if (event_add(&device_ev, NULL) < 0) {
|
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "event_add failed: %s", strerror(errno));
|
|
||||||
devops.close();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Run tinc-up script to further initialize the tap interface */
|
/* Run tinc-up script to further initialize the tap interface */
|
||||||
char *envp[5];
|
char *envp[5];
|
||||||
|
@ -805,27 +828,16 @@ static bool setup_myself(void) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
listen_socket[i].tcp = i + 3;
|
|
||||||
|
|
||||||
#ifdef FD_CLOEXEC
|
#ifdef FD_CLOEXEC
|
||||||
fcntl(i + 3, F_SETFD, FD_CLOEXEC);
|
fcntl(i + 3, F_SETFD, FD_CLOEXEC);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
listen_socket[i].udp = setup_vpn_in_socket(&sa);
|
int udp_fd = setup_vpn_in_socket(&sa);
|
||||||
if(listen_socket[i].udp < 0)
|
if(udp_fd < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
event_set(&listen_socket[i].ev_tcp, listen_socket[i].tcp, EV_READ|EV_PERSIST, handle_new_meta_connection, NULL);
|
io_add(&listen_socket[i].tcp, (io_cb_t)handle_new_meta_connection, &listen_socket[i], i + 3, IO_READ);
|
||||||
if(event_add(&listen_socket[i].ev_tcp, NULL) < 0) {
|
io_add(&listen_socket[i].udp, (io_cb_t)handle_incoming_vpn_data, &listen_socket[i], udp_fd, IO_READ);
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "event_add failed: %s", strerror(errno));
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
event_set(&listen_socket[i].ev_udp, listen_socket[i].udp, EV_READ|EV_PERSIST, handle_incoming_vpn_data, (void *)(intptr_t)listen_sockets);
|
|
||||||
if(event_add(&listen_socket[listen_sockets].ev_udp, NULL) < 0) {
|
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "event_add failed: %s", strerror(errno));
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(debug_level >= DEBUG_CONNECTIONS) {
|
if(debug_level >= DEBUG_CONNECTIONS) {
|
||||||
hostname = sockaddr2hostname(&sa);
|
hostname = sockaddr2hostname(&sa);
|
||||||
|
@ -878,37 +890,20 @@ static bool setup_myself(void) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
listen_socket[listen_sockets].tcp =
|
int tcp_fd = setup_listen_socket((sockaddr_t *) aip->ai_addr);
|
||||||
setup_listen_socket((sockaddr_t *) aip->ai_addr);
|
|
||||||
|
|
||||||
if(listen_socket[listen_sockets].tcp < 0)
|
if(tcp_fd < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
listen_socket[listen_sockets].udp =
|
int udp_fd = setup_vpn_in_socket((sockaddr_t *) aip->ai_addr);
|
||||||
setup_vpn_in_socket((sockaddr_t *) aip->ai_addr);
|
|
||||||
|
|
||||||
if(listen_socket[listen_sockets].udp < 0) {
|
if(tcp_fd < 0) {
|
||||||
close(listen_socket[listen_sockets].tcp);
|
close(tcp_fd);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
event_set(&listen_socket[listen_sockets].ev_tcp,
|
io_add(&listen_socket[listen_sockets].tcp, handle_new_meta_connection, &listen_socket[listen_sockets], tcp_fd, IO_READ);
|
||||||
listen_socket[listen_sockets].tcp,
|
io_add(&listen_socket[listen_sockets].udp, handle_incoming_vpn_data, &listen_socket[listen_sockets], udp_fd, IO_READ);
|
||||||
EV_READ|EV_PERSIST,
|
|
||||||
handle_new_meta_connection, NULL);
|
|
||||||
if(event_add(&listen_socket[listen_sockets].ev_tcp, NULL) < 0) {
|
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "event_add failed: %s", strerror(errno));
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
event_set(&listen_socket[listen_sockets].ev_udp,
|
|
||||||
listen_socket[listen_sockets].udp,
|
|
||||||
EV_READ|EV_PERSIST,
|
|
||||||
handle_incoming_vpn_data, (void *)(intptr_t)listen_sockets);
|
|
||||||
if(event_add(&listen_socket[listen_sockets].ev_udp, NULL) < 0) {
|
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "event_add failed: %s", strerror(errno));
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(debug_level >= DEBUG_CONNECTIONS) {
|
if(debug_level >= DEBUG_CONNECTIONS) {
|
||||||
hostname = sockaddr2hostname((sockaddr_t *) aip->ai_addr);
|
hostname = sockaddr2hostname((sockaddr_t *) aip->ai_addr);
|
||||||
|
@ -990,10 +985,10 @@ void close_network_connections(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < listen_sockets; i++) {
|
for(int i = 0; i < listen_sockets; i++) {
|
||||||
event_del(&listen_socket[i].ev_tcp);
|
io_del(&listen_socket[i].tcp);
|
||||||
event_del(&listen_socket[i].ev_udp);
|
io_del(&listen_socket[i].udp);
|
||||||
close(listen_socket[i].tcp);
|
close(listen_socket[i].tcp.fd);
|
||||||
close(listen_socket[i].udp);
|
close(listen_socket[i].udp.fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *envp[5];
|
char *envp[5];
|
||||||
|
|
|
@ -271,7 +271,7 @@ int setup_vpn_in_socket(const sockaddr_t *sa) {
|
||||||
return nfd;
|
return nfd;
|
||||||
} /* int setup_vpn_in_socket */
|
} /* int setup_vpn_in_socket */
|
||||||
|
|
||||||
static void retry_outgoing_handler(int fd, short events, void *data) {
|
static void retry_outgoing_handler(void *data) {
|
||||||
setup_outgoing_connection(data);
|
setup_outgoing_connection(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,12 +281,9 @@ void retry_outgoing(outgoing_t *outgoing) {
|
||||||
if(outgoing->timeout > maxtimeout)
|
if(outgoing->timeout > maxtimeout)
|
||||||
outgoing->timeout = maxtimeout;
|
outgoing->timeout = maxtimeout;
|
||||||
|
|
||||||
timeout_set(&outgoing->ev, retry_outgoing_handler, outgoing);
|
timeout_add(&outgoing->ev, retry_outgoing_handler, outgoing, &(struct timeval){outgoing->timeout, rand() % 100000});
|
||||||
event_add(&outgoing->ev, &(struct timeval){outgoing->timeout, 0});
|
|
||||||
|
|
||||||
logger(DEBUG_CONNECTIONS, LOG_NOTICE,
|
logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Trying to re-establish outgoing connection in %d seconds", outgoing->timeout);
|
||||||
"Trying to re-establish outgoing connection in %d seconds",
|
|
||||||
outgoing->timeout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void finish_connecting(connection_t *c) {
|
void finish_connecting(connection_t *c) {
|
||||||
|
@ -349,9 +346,7 @@ static void do_outgoing_pipe(connection_t *c, char *command) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_meta_write(int sock, short events, void *data) {
|
static void handle_meta_write(connection_t *c) {
|
||||||
connection_t *c = data;
|
|
||||||
|
|
||||||
ssize_t outlen = send(c->socket, c->outbuf.data + c->outbuf.offset, c->outbuf.len - c->outbuf.offset, 0);
|
ssize_t outlen = send(c->socket, c->outbuf.data + c->outbuf.offset, c->outbuf.len - c->outbuf.offset, 0);
|
||||||
if(outlen <= 0) {
|
if(outlen <= 0) {
|
||||||
if(!errno || errno == EPIPE) {
|
if(!errno || errno == EPIPE) {
|
||||||
|
@ -368,10 +363,16 @@ static void handle_meta_write(int sock, short events, void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer_read(&c->outbuf, outlen);
|
buffer_read(&c->outbuf, outlen);
|
||||||
if(!c->outbuf.len && event_initialized(&c->outevent))
|
if(!c->outbuf.len)
|
||||||
event_del(&c->outevent);
|
io_set(&c->io, IO_READ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_meta_io(void *data, int flags) {
|
||||||
|
if(flags & IO_WRITE)
|
||||||
|
handle_meta_write(data);
|
||||||
|
else
|
||||||
|
handle_meta_connection_data(data);
|
||||||
|
}
|
||||||
|
|
||||||
bool do_outgoing_connection(outgoing_t *outgoing) {
|
bool do_outgoing_connection(outgoing_t *outgoing) {
|
||||||
char *address, *port, *space;
|
char *address, *port, *space;
|
||||||
|
@ -487,16 +488,13 @@ begin:
|
||||||
|
|
||||||
connection_add(c);
|
connection_add(c);
|
||||||
|
|
||||||
event_set(&c->inevent, c->socket, EV_READ | EV_PERSIST, handle_meta_connection_data, c);
|
io_add(&c->io, handle_meta_io, c, c->socket, IO_READ);
|
||||||
event_set(&c->outevent, c->socket, EV_WRITE | EV_PERSIST, handle_meta_write, c);
|
|
||||||
event_add(&c->inevent, NULL);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup_outgoing_connection(outgoing_t *outgoing) {
|
void setup_outgoing_connection(outgoing_t *outgoing) {
|
||||||
if(event_initialized(&outgoing->ev))
|
timeout_del(&outgoing->ev);
|
||||||
event_del(&outgoing->ev);
|
|
||||||
|
|
||||||
node_t *n = lookup_node(outgoing->name);
|
node_t *n = lookup_node(outgoing->name);
|
||||||
|
|
||||||
|
@ -523,13 +521,14 @@ void setup_outgoing_connection(outgoing_t *outgoing) {
|
||||||
accept a new tcp connect and create a
|
accept a new tcp connect and create a
|
||||||
new connection
|
new connection
|
||||||
*/
|
*/
|
||||||
void handle_new_meta_connection(int sock, short events, void *data) {
|
void handle_new_meta_connection(void *data, int flags) {
|
||||||
|
listen_socket_t *l = data;
|
||||||
connection_t *c;
|
connection_t *c;
|
||||||
sockaddr_t sa;
|
sockaddr_t sa;
|
||||||
int fd;
|
int fd;
|
||||||
socklen_t len = sizeof sa;
|
socklen_t len = sizeof sa;
|
||||||
|
|
||||||
fd = accept(sock, &sa.sa, &len);
|
fd = accept(l->tcp.fd, &sa.sa, &len);
|
||||||
|
|
||||||
if(fd < 0) {
|
if(fd < 0) {
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno));
|
logger(DEBUG_ALWAYS, LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno));
|
||||||
|
@ -552,9 +551,7 @@ void handle_new_meta_connection(int sock, short events, void *data) {
|
||||||
|
|
||||||
logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection from %s", c->hostname);
|
logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection from %s", c->hostname);
|
||||||
|
|
||||||
event_set(&c->inevent, c->socket, EV_READ | EV_PERSIST, handle_meta_connection_data, c);
|
io_add(&c->io, handle_meta_io, c, c->socket, IO_READ);
|
||||||
event_set(&c->outevent, c->socket, EV_WRITE | EV_PERSIST, handle_meta_write, c);
|
|
||||||
event_add(&c->inevent, NULL);
|
|
||||||
|
|
||||||
configure_tcp(c);
|
configure_tcp(c);
|
||||||
|
|
||||||
|
@ -565,8 +562,7 @@ void handle_new_meta_connection(int sock, short events, void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_outgoing(outgoing_t *outgoing) {
|
static void free_outgoing(outgoing_t *outgoing) {
|
||||||
if(event_initialized(&outgoing->ev))
|
timeout_del(&outgoing->ev);
|
||||||
event_del(&outgoing->ev);
|
|
||||||
|
|
||||||
if(outgoing->ai)
|
if(outgoing->ai)
|
||||||
freeaddrinfo(outgoing->ai);
|
freeaddrinfo(outgoing->ai);
|
||||||
|
|
|
@ -52,7 +52,7 @@ struct addrinfo *str2addrinfo(const char *address, const char *service, int sock
|
||||||
|
|
||||||
sockaddr_t str2sockaddr(const char *address, const char *port) {
|
sockaddr_t str2sockaddr(const char *address, const char *port) {
|
||||||
struct addrinfo *ai, hint = {0};
|
struct addrinfo *ai, hint = {0};
|
||||||
sockaddr_t result;
|
sockaddr_t result = {{0}};
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
hint.ai_family = AF_UNSPEC;
|
hint.ai_family = AF_UNSPEC;
|
||||||
|
|
10
src/node.c
10
src/node.c
|
@ -78,8 +78,7 @@ void free_node(node_t *n) {
|
||||||
ecdsa_free(&n->ecdsa);
|
ecdsa_free(&n->ecdsa);
|
||||||
sptps_stop(&n->sptps);
|
sptps_stop(&n->sptps);
|
||||||
|
|
||||||
if(timeout_initialized(&n->mtuevent))
|
timeout_del(&n->mtutimeout);
|
||||||
event_del(&n->mtuevent);
|
|
||||||
|
|
||||||
if(n->hostname)
|
if(n->hostname)
|
||||||
free(n->hostname);
|
free(n->hostname);
|
||||||
|
@ -129,6 +128,13 @@ void update_node_udp(node_t *n, const sockaddr_t *sa) {
|
||||||
|
|
||||||
if(sa) {
|
if(sa) {
|
||||||
n->address = *sa;
|
n->address = *sa;
|
||||||
|
n->sock = 0;
|
||||||
|
for(int i = 0; i < listen_sockets; i++) {
|
||||||
|
if(listen_socket[i].sa.sa.sa_family == sa->sa.sa_family) {
|
||||||
|
n->sock = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
hash_insert(node_udp_cache, sa, n);
|
hash_insert(node_udp_cache, sa, n);
|
||||||
free(n->hostname);
|
free(n->hostname);
|
||||||
n->hostname = sockaddr2hostname(&n->address);
|
n->hostname = sockaddr2hostname(&n->address);
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "cipher.h"
|
#include "cipher.h"
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
#include "digest.h"
|
#include "digest.h"
|
||||||
|
#include "event.h"
|
||||||
#include "subnet.h"
|
#include "subnet.h"
|
||||||
|
|
||||||
typedef struct node_status_t {
|
typedef struct node_status_t {
|
||||||
|
@ -83,7 +84,7 @@ typedef struct node_t {
|
||||||
length_t minmtu; /* Probed minimum MTU */
|
length_t minmtu; /* Probed minimum MTU */
|
||||||
length_t maxmtu; /* Probed maximum MTU */
|
length_t maxmtu; /* Probed maximum MTU */
|
||||||
int mtuprobes; /* Number of probes */
|
int mtuprobes; /* Number of probes */
|
||||||
struct event mtuevent; /* Probe event */
|
timeout_t mtutimeout; /* Probe event */
|
||||||
|
|
||||||
uint64_t in_packets;
|
uint64_t in_packets;
|
||||||
uint64_t in_bytes;
|
uint64_t in_bytes;
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "edge.h"
|
#include "edge.h"
|
||||||
|
#include "event.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
|
@ -127,7 +128,7 @@ DWORD WINAPI controlhandler(DWORD request, DWORD type, LPVOID boe, LPVOID bah) {
|
||||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
event_loopexit(NULL);
|
event_exit();
|
||||||
status.dwWaitHint = 30000;
|
status.dwWaitHint = 30000;
|
||||||
status.dwCurrentState = SERVICE_STOP_PENDING;
|
status.dwCurrentState = SERVICE_STOP_PENDING;
|
||||||
SetServiceStatus(statushandle, &status);
|
SetServiceStatus(statushandle, &status);
|
||||||
|
|
|
@ -165,7 +165,24 @@ static void free_past_request(past_request_t *r) {
|
||||||
free(r);
|
free(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct event past_request_event;
|
static timeout_t past_request_timeout;
|
||||||
|
|
||||||
|
static void age_past_requests(void *data) {
|
||||||
|
int left = 0, deleted = 0;
|
||||||
|
|
||||||
|
for splay_each(past_request_t, p, past_request_tree) {
|
||||||
|
if(p->firstseen + pinginterval <= now.tv_sec)
|
||||||
|
splay_delete_node(past_request_tree, node), deleted++;
|
||||||
|
else
|
||||||
|
left++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(left || deleted)
|
||||||
|
logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Aging past requests: deleted %d, left %d", deleted, left);
|
||||||
|
|
||||||
|
if(left)
|
||||||
|
timeout_set(&past_request_timeout, &(struct timeval){10, rand() % 100000});
|
||||||
|
}
|
||||||
|
|
||||||
bool seen_request(const char *request) {
|
bool seen_request(const char *request) {
|
||||||
past_request_t *new, p = {NULL};
|
past_request_t *new, p = {NULL};
|
||||||
|
@ -180,39 +197,17 @@ bool seen_request(const char *request) {
|
||||||
new->request = xstrdup(request);
|
new->request = xstrdup(request);
|
||||||
new->firstseen = time(NULL);
|
new->firstseen = time(NULL);
|
||||||
splay_insert(past_request_tree, new);
|
splay_insert(past_request_tree, new);
|
||||||
event_add(&past_request_event, &(struct timeval){10, 0});
|
timeout_add(&past_request_timeout, age_past_requests, NULL, &(struct timeval){10, rand() % 100000});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void age_past_requests(int fd, short events, void *data) {
|
|
||||||
int left = 0, deleted = 0;
|
|
||||||
time_t now = time(NULL);
|
|
||||||
|
|
||||||
for splay_each(past_request_t, p, past_request_tree) {
|
|
||||||
if(p->firstseen + pinginterval <= now)
|
|
||||||
splay_delete_node(past_request_tree, node), deleted++;
|
|
||||||
else
|
|
||||||
left++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(left || deleted)
|
|
||||||
logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Aging past requests: deleted %d, left %d",
|
|
||||||
deleted, left);
|
|
||||||
|
|
||||||
if(left)
|
|
||||||
event_add(&past_request_event, &(struct timeval){10, 0});
|
|
||||||
}
|
|
||||||
|
|
||||||
void init_requests(void) {
|
void init_requests(void) {
|
||||||
past_request_tree = splay_alloc_tree((splay_compare_t) past_request_compare, (splay_action_t) free_past_request);
|
past_request_tree = splay_alloc_tree((splay_compare_t) past_request_compare, (splay_action_t) free_past_request);
|
||||||
|
|
||||||
timeout_set(&past_request_event, age_past_requests, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void exit_requests(void) {
|
void exit_requests(void) {
|
||||||
splay_delete_tree(past_request_tree);
|
splay_delete_tree(past_request_tree);
|
||||||
|
|
||||||
if(timeout_initialized(&past_request_event))
|
timeout_del(&past_request_timeout);
|
||||||
event_del(&past_request_event);
|
|
||||||
}
|
}
|
||||||
|
|
120
src/route.c
120
src/route.c
|
@ -59,7 +59,7 @@ static const size_t opt_size = sizeof(struct nd_opt_hdr);
|
||||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static struct event age_subnets_event;
|
static timeout_t age_subnets_timeout;
|
||||||
|
|
||||||
/* RFC 1071 */
|
/* RFC 1071 */
|
||||||
|
|
||||||
|
@ -84,13 +84,12 @@ static uint16_t inet_checksum(void *data, int len, uint16_t prevsum) {
|
||||||
static bool ratelimit(int frequency) {
|
static bool ratelimit(int frequency) {
|
||||||
static time_t lasttime = 0;
|
static time_t lasttime = 0;
|
||||||
static int count = 0;
|
static int count = 0;
|
||||||
time_t now = time(NULL);
|
|
||||||
|
|
||||||
if(lasttime == now) {
|
if(lasttime == now.tv_sec) {
|
||||||
if(count >= frequency)
|
if(count >= frequency)
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
lasttime = now;
|
lasttime = now.tv_sec;
|
||||||
count = 0;
|
count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,15 +114,22 @@ static void clamp_mss(const node_t *source, const node_t *via, vpn_packet_t *pac
|
||||||
mtu = via->mtu;
|
mtu = via->mtu;
|
||||||
|
|
||||||
/* Find TCP header */
|
/* Find TCP header */
|
||||||
int start = 0;
|
int start = ether_size;
|
||||||
uint16_t type = packet->data[12] << 8 | packet->data[13];
|
uint16_t type = packet->data[12] << 8 | packet->data[13];
|
||||||
|
|
||||||
if(type == ETH_P_IP && packet->data[23] == 6)
|
if(type == ETH_P_8021Q) {
|
||||||
start = 14 + (packet->data[14] & 0xf) * 4;
|
start += 4;
|
||||||
else if(type == ETH_P_IPV6 && packet->data[20] == 6)
|
type = packet->data[16] << 8 | packet->data[17];
|
||||||
start = 14 + 40;
|
}
|
||||||
|
|
||||||
if(!start || packet->len <= start + 20)
|
if(type == ETH_P_IP && packet->data[start + 9] == 6)
|
||||||
|
start += (packet->data[start] & 0xf) * 4;
|
||||||
|
else if(type == ETH_P_IPV6 && packet->data[start + 6] == 6)
|
||||||
|
start += 40;
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(packet->len <= start + 20)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Use data offset field to calculate length of options field */
|
/* Use data offset field to calculate length of options field */
|
||||||
|
@ -185,12 +191,11 @@ static void swap_mac_addresses(vpn_packet_t *packet) {
|
||||||
memcpy(&packet->data[6], &tmp, sizeof tmp);
|
memcpy(&packet->data[6], &tmp, sizeof tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void age_subnets(int fd, short events, void *data) {
|
static void age_subnets(void *data) {
|
||||||
bool left = false;
|
bool left = false;
|
||||||
time_t now = time(NULL);
|
|
||||||
|
|
||||||
for splay_each(subnet_t, s, myself->subnet_tree) {
|
for splay_each(subnet_t, s, myself->subnet_tree) {
|
||||||
if(s->expires && s->expires < now) {
|
if(s->expires && s->expires < now.tv_sec) {
|
||||||
if(debug_level >= DEBUG_TRAFFIC) {
|
if(debug_level >= DEBUG_TRAFFIC) {
|
||||||
char netstr[MAXNETSTR];
|
char netstr[MAXNETSTR];
|
||||||
if(net2str(netstr, sizeof netstr, s))
|
if(net2str(netstr, sizeof netstr, s))
|
||||||
|
@ -209,7 +214,7 @@ static void age_subnets(int fd, short events, void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(left)
|
if(left)
|
||||||
event_add(&age_subnets_event, &(struct timeval){10, 0});
|
timeout_set(&age_subnets_timeout, &(struct timeval){10, rand() % 100000});
|
||||||
}
|
}
|
||||||
|
|
||||||
static void learn_mac(mac_t *address) {
|
static void learn_mac(mac_t *address) {
|
||||||
|
@ -236,9 +241,7 @@ static void learn_mac(mac_t *address) {
|
||||||
if(c->status.active)
|
if(c->status.active)
|
||||||
send_add_subnet(c, subnet);
|
send_add_subnet(c, subnet);
|
||||||
|
|
||||||
if(!timeout_initialized(&age_subnets_event))
|
timeout_add(&age_subnets_timeout, age_subnets, NULL, &(struct timeval){10, rand() % 100000});
|
||||||
timeout_set(&age_subnets_event, age_subnets, NULL);
|
|
||||||
event_add(&age_subnets_event, &(struct timeval){10, 0});
|
|
||||||
} else {
|
} else {
|
||||||
if(subnet->expires)
|
if(subnet->expires)
|
||||||
subnet->expires = time(NULL) + macexpire;
|
subnet->expires = time(NULL) + macexpire;
|
||||||
|
@ -247,7 +250,7 @@ static void learn_mac(mac_t *address) {
|
||||||
|
|
||||||
/* RFC 792 */
|
/* RFC 792 */
|
||||||
|
|
||||||
static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, uint8_t type, uint8_t code) {
|
static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, length_t ether_size, uint8_t type, uint8_t code) {
|
||||||
struct ip ip = {0};
|
struct ip ip = {0};
|
||||||
struct icmp icmp = {0};
|
struct icmp icmp = {0};
|
||||||
|
|
||||||
|
@ -320,7 +323,7 @@ static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, uint8_t
|
||||||
|
|
||||||
/* RFC 791 */
|
/* RFC 791 */
|
||||||
|
|
||||||
static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet) {
|
static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t ether_size) {
|
||||||
struct ip ip;
|
struct ip ip;
|
||||||
vpn_packet_t fragment;
|
vpn_packet_t fragment;
|
||||||
int len, maxlen, todo;
|
int len, maxlen, todo;
|
||||||
|
@ -384,7 +387,7 @@ static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) {
|
||||||
dest.x[2],
|
dest.x[2],
|
||||||
dest.x[3]);
|
dest.x[3]);
|
||||||
|
|
||||||
route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_UNKNOWN);
|
route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_UNKNOWN);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,10 +397,10 @@ static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!subnet->owner->status.reachable)
|
if(!subnet->owner->status.reachable)
|
||||||
return route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_UNREACH);
|
return route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_UNREACH);
|
||||||
|
|
||||||
if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself)
|
if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself)
|
||||||
return route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_ANO);
|
return route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_ANO);
|
||||||
|
|
||||||
if(priorityinheritance)
|
if(priorityinheritance)
|
||||||
packet->priority = packet->data[15];
|
packet->priority = packet->data[15];
|
||||||
|
@ -410,15 +413,15 @@ static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(directonly && subnet->owner != via)
|
if(directonly && subnet->owner != via)
|
||||||
return route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_ANO);
|
return route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_ANO);
|
||||||
|
|
||||||
if(via && packet->len > MAX(via->mtu, 590) && via != myself) {
|
if(via && packet->len > MAX(via->mtu, 590) && via != myself) {
|
||||||
logger(DEBUG_TRAFFIC, LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu);
|
logger(DEBUG_TRAFFIC, 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) {
|
if(packet->data[20] & 0x40) {
|
||||||
packet->len = MAX(via->mtu, 590);
|
packet->len = MAX(via->mtu, 590);
|
||||||
route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED);
|
route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED);
|
||||||
} else {
|
} else {
|
||||||
fragment_ipv4_packet(via, packet);
|
fragment_ipv4_packet(via, packet, ether_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -445,7 +448,7 @@ static void route_ipv4(node_t *source, vpn_packet_t *packet) {
|
||||||
|
|
||||||
/* RFC 2463 */
|
/* RFC 2463 */
|
||||||
|
|
||||||
static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, uint8_t type, uint8_t code) {
|
static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, length_t ether_size, uint8_t type, uint8_t code) {
|
||||||
struct ip6_hdr ip6;
|
struct ip6_hdr ip6;
|
||||||
struct icmp6_hdr icmp6 = {0};
|
struct icmp6_hdr icmp6 = {0};
|
||||||
uint16_t checksum;
|
uint16_t checksum;
|
||||||
|
@ -543,7 +546,7 @@ static void route_ipv6_unicast(node_t *source, vpn_packet_t *packet) {
|
||||||
ntohs(dest.x[6]),
|
ntohs(dest.x[6]),
|
||||||
ntohs(dest.x[7]));
|
ntohs(dest.x[7]));
|
||||||
|
|
||||||
route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR);
|
route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -553,10 +556,10 @@ static void route_ipv6_unicast(node_t *source, vpn_packet_t *packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!subnet->owner->status.reachable)
|
if(!subnet->owner->status.reachable)
|
||||||
return route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE);
|
return route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE);
|
||||||
|
|
||||||
if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself)
|
if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself)
|
||||||
return route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN);
|
return route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN);
|
||||||
|
|
||||||
via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via;
|
via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via;
|
||||||
|
|
||||||
|
@ -566,12 +569,12 @@ static void route_ipv6_unicast(node_t *source, vpn_packet_t *packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(directonly && subnet->owner != via)
|
if(directonly && subnet->owner != via)
|
||||||
return route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN);
|
return route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN);
|
||||||
|
|
||||||
if(via && packet->len > MAX(via->mtu, 1294) && via != myself) {
|
if(via && packet->len > MAX(via->mtu, 1294) && via != myself) {
|
||||||
logger(DEBUG_TRAFFIC, LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu);
|
logger(DEBUG_TRAFFIC, 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);
|
packet->len = MAX(via->mtu, 1294);
|
||||||
route_ipv6_unreachable(source, packet, ICMP6_PACKET_TOO_BIG, 0);
|
route_ipv6_unreachable(source, packet, ether_size, ICMP6_PACKET_TOO_BIG, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -842,17 +845,24 @@ static void route_mac(node_t *source, vpn_packet_t *packet) {
|
||||||
if(via && packet->len > via->mtu && via != myself) {
|
if(via && packet->len > via->mtu && via != myself) {
|
||||||
logger(DEBUG_TRAFFIC, LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu);
|
logger(DEBUG_TRAFFIC, LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu);
|
||||||
uint16_t type = packet->data[12] << 8 | packet->data[13];
|
uint16_t type = packet->data[12] << 8 | packet->data[13];
|
||||||
if(type == ETH_P_IP && packet->len > 590) {
|
length_t ethlen = 14;
|
||||||
if(packet->data[20] & 0x40) {
|
|
||||||
|
if(type == ETH_P_8021Q) {
|
||||||
|
type = packet->data[16] << 8 | packet->data[17];
|
||||||
|
ethlen += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(type == ETH_P_IP && packet->len > 576 + ethlen) {
|
||||||
|
if(packet->data[6 + ethlen] & 0x40) {
|
||||||
packet->len = via->mtu;
|
packet->len = via->mtu;
|
||||||
route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED);
|
route_ipv4_unreachable(source, packet, ethlen, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED);
|
||||||
} else {
|
} else {
|
||||||
fragment_ipv4_packet(via, packet);
|
fragment_ipv4_packet(via, packet, ethlen);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else if(type == ETH_P_IPV6 && packet->len > 1294) {
|
} else if(type == ETH_P_IPV6 && packet->len > 1280 + ethlen) {
|
||||||
packet->len = via->mtu;
|
packet->len = via->mtu;
|
||||||
route_ipv6_unreachable(source, packet, ICMP6_PACKET_TOO_BIG, 0);
|
route_ipv6_unreachable(source, packet, ethlen, ICMP6_PACKET_TOO_BIG, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -881,42 +891,48 @@ static void send_pcap(vpn_packet_t *packet) {
|
||||||
|
|
||||||
static bool do_decrement_ttl(node_t *source, vpn_packet_t *packet) {
|
static bool do_decrement_ttl(node_t *source, vpn_packet_t *packet) {
|
||||||
uint16_t type = packet->data[12] << 8 | packet->data[13];
|
uint16_t type = packet->data[12] << 8 | packet->data[13];
|
||||||
|
length_t ethlen = ether_size;
|
||||||
|
|
||||||
|
if(type == ETH_P_8021Q) {
|
||||||
|
type = packet->data[16] << 8 | packet->data[17];
|
||||||
|
ethlen += 4;
|
||||||
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ETH_P_IP:
|
case ETH_P_IP:
|
||||||
if(!checklength(source, packet, 14 + 32))
|
if(!checklength(source, packet, ethlen + ip_size))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(packet->data[22] < 1) {
|
if(packet->data[ethlen + 8] < 1) {
|
||||||
if(packet->data[25] != IPPROTO_ICMP || packet->data[46] != ICMP_TIME_EXCEEDED)
|
if(packet->data[ethlen + 11] != IPPROTO_ICMP || packet->data[ethlen + 32] != ICMP_TIME_EXCEEDED)
|
||||||
route_ipv4_unreachable(source, packet, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL);
|
route_ipv4_unreachable(source, packet, ethlen, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t old = packet->data[22] << 8 | packet->data[23];
|
uint16_t old = packet->data[ethlen + 8] << 8 | packet->data[ethlen + 9];
|
||||||
packet->data[22]--;
|
packet->data[ethlen + 8]--;
|
||||||
uint16_t new = packet->data[22] << 8 | packet->data[23];
|
uint16_t new = packet->data[ethlen + 8] << 8 | packet->data[ethlen + 9];
|
||||||
|
|
||||||
uint32_t checksum = packet->data[24] << 8 | packet->data[25];
|
uint32_t checksum = packet->data[ethlen + 10] << 8 | packet->data[ethlen + 11];
|
||||||
checksum += old + (~new & 0xFFFF);
|
checksum += old + (~new & 0xFFFF);
|
||||||
while(checksum >> 16)
|
while(checksum >> 16)
|
||||||
checksum = (checksum & 0xFFFF) + (checksum >> 16);
|
checksum = (checksum & 0xFFFF) + (checksum >> 16);
|
||||||
packet->data[24] = checksum >> 8;
|
packet->data[ethlen + 10] = checksum >> 8;
|
||||||
packet->data[25] = checksum & 0xff;
|
packet->data[ethlen + 11] = checksum & 0xff;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case ETH_P_IPV6:
|
case ETH_P_IPV6:
|
||||||
if(!checklength(source, packet, 14 + 40))
|
if(!checklength(source, packet, ethlen + ip6_size))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(packet->data[21] < 1) {
|
if(packet->data[ethlen + 7] < 1) {
|
||||||
if(packet->data[20] != IPPROTO_ICMPV6 || packet->data[54] != ICMP6_TIME_EXCEEDED)
|
if(packet->data[ethlen + 6] != IPPROTO_ICMPV6 || packet->data[ethlen + 40] != ICMP6_TIME_EXCEEDED)
|
||||||
route_ipv6_unreachable(source, packet, ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_TRANSIT);
|
route_ipv6_unreachable(source, packet, ethlen, ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_TRANSIT);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
packet->data[21]--;
|
packet->data[ethlen + 7]--;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
|
@ -398,6 +398,8 @@ splay_node_t *splay_insert_node(splay_tree_t *tree, splay_node_t *node) {
|
||||||
splay_node_t *closest;
|
splay_node_t *closest;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
node->left = node->right = node->parent = node->next = node->prev = NULL;
|
||||||
|
|
||||||
if(!tree->root)
|
if(!tree->root)
|
||||||
splay_insert_top(tree, node);
|
splay_insert_top(tree, node);
|
||||||
else {
|
else {
|
||||||
|
@ -418,6 +420,7 @@ splay_node_t *splay_insert_node(splay_tree_t *tree, splay_node_t *node) {
|
||||||
void splay_insert_top(splay_tree_t *tree, splay_node_t *node) {
|
void splay_insert_top(splay_tree_t *tree, splay_node_t *node) {
|
||||||
node->prev = node->next = node->left = node->right = node->parent = NULL;
|
node->prev = node->next = node->left = node->right = node->parent = NULL;
|
||||||
tree->head = tree->tail = tree->root = node;
|
tree->head = tree->tail = tree->root = node;
|
||||||
|
tree->count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void splay_insert_before(splay_tree_t *tree, splay_node_t *before, splay_node_t *node) {
|
void splay_insert_before(splay_tree_t *tree, splay_node_t *before, splay_node_t *node) {
|
||||||
|
@ -446,6 +449,7 @@ void splay_insert_before(splay_tree_t *tree, splay_node_t *before, splay_node_t
|
||||||
|
|
||||||
node->parent = NULL;
|
node->parent = NULL;
|
||||||
tree->root = node;
|
tree->root = node;
|
||||||
|
tree->count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void splay_insert_after(splay_tree_t *tree, splay_node_t *after, splay_node_t *node) {
|
void splay_insert_after(splay_tree_t *tree, splay_node_t *after, splay_node_t *node) {
|
||||||
|
@ -474,6 +478,7 @@ void splay_insert_after(splay_tree_t *tree, splay_node_t *after, splay_node_t *n
|
||||||
|
|
||||||
node->parent = NULL;
|
node->parent = NULL;
|
||||||
tree->root = node;
|
tree->root = node;
|
||||||
|
tree->count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
splay_node_t *splay_unlink(splay_tree_t *tree, void *data) {
|
splay_node_t *splay_unlink(splay_tree_t *tree, void *data) {
|
||||||
|
@ -511,6 +516,8 @@ void splay_unlink_node(splay_tree_t *tree, splay_node_t *node) {
|
||||||
} else {
|
} else {
|
||||||
tree->root = NULL;
|
tree->root = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tree->count--;
|
||||||
}
|
}
|
||||||
|
|
||||||
void splay_delete_node(splay_tree_t *tree, splay_node_t *node) {
|
void splay_delete_node(splay_tree_t *tree, splay_node_t *node) {
|
||||||
|
|
|
@ -58,6 +58,8 @@ typedef struct splay_tree_t {
|
||||||
splay_compare_t compare;
|
splay_compare_t compare;
|
||||||
splay_action_t delete;
|
splay_action_t delete;
|
||||||
|
|
||||||
|
int count;
|
||||||
|
|
||||||
} splay_tree_t;
|
} splay_tree_t;
|
||||||
|
|
||||||
/* (De)constructors */
|
/* (De)constructors */
|
||||||
|
|
|
@ -29,6 +29,7 @@ bool send_request(void *c, const char *msg, ...) { return false; }
|
||||||
struct list_t *connection_list = NULL;
|
struct list_t *connection_list = NULL;
|
||||||
bool send_meta(void *c, const char *msg , int len) { return false; }
|
bool send_meta(void *c, const char *msg , int len) { return false; }
|
||||||
char *logfilename = NULL;
|
char *logfilename = NULL;
|
||||||
|
struct timeval now;
|
||||||
|
|
||||||
ecdsa_t mykey, hiskey;
|
ecdsa_t mykey, hiskey;
|
||||||
|
|
||||||
|
|
|
@ -57,11 +57,12 @@ static char *name = NULL;
|
||||||
static char *identname = NULL; /* program name for syslog */
|
static char *identname = NULL; /* program name for syslog */
|
||||||
static char *pidfilename = NULL; /* pid file location */
|
static char *pidfilename = NULL; /* pid file location */
|
||||||
static char *confdir = NULL;
|
static char *confdir = NULL;
|
||||||
static char controlcookie[1024];
|
static char controlcookie[1025];
|
||||||
char *netname = NULL;
|
char *netname = NULL;
|
||||||
char *confbase = NULL;
|
char *confbase = NULL;
|
||||||
static char *tinc_conf = NULL;
|
static char *tinc_conf = NULL;
|
||||||
static char *hosts_dir = NULL;
|
static char *hosts_dir = NULL;
|
||||||
|
struct timeval now;
|
||||||
|
|
||||||
// Horrible global variables...
|
// Horrible global variables...
|
||||||
static int pid = 0;
|
static int pid = 0;
|
||||||
|
@ -134,7 +135,7 @@ static void usage(bool status) {
|
||||||
" generate-rsa-keys [bits] Generate a new RSA public/private keypair.\n"
|
" generate-rsa-keys [bits] Generate a new RSA public/private keypair.\n"
|
||||||
" generate-ecdsa-keys Generate a new ECDSA public/private keypair.\n"
|
" generate-ecdsa-keys Generate a new ECDSA public/private keypair.\n"
|
||||||
" dump Dump a list of one of the following things:\n"
|
" dump Dump a list of one of the following things:\n"
|
||||||
" nodes - all known nodes in the VPN\n"
|
" [reachable] nodes - all known nodes in the VPN\n"
|
||||||
" edges - all known connections in the VPN\n"
|
" edges - all known connections in the VPN\n"
|
||||||
" subnets - all known subnets in the VPN\n"
|
" subnets - all known subnets in the VPN\n"
|
||||||
" connections - all meta connections with ourself\n"
|
" connections - all meta connections with ourself\n"
|
||||||
|
@ -708,8 +709,8 @@ static bool connect_tincd(bool verbose) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
char host[128];
|
char host[129];
|
||||||
char port[128];
|
char port[129];
|
||||||
|
|
||||||
if(fscanf(f, "%20d %1024s %128s port %128s", &pid, controlcookie, host, port) != 4) {
|
if(fscanf(f, "%20d %1024s %128s port %128s", &pid, controlcookie, host, port) != 4) {
|
||||||
if(verbose)
|
if(verbose)
|
||||||
|
@ -911,6 +912,19 @@ static int cmd_reload(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cmd_dump(int argc, char *argv[]) {
|
static int cmd_dump(int argc, char *argv[]) {
|
||||||
|
bool only_reachable = false;
|
||||||
|
|
||||||
|
if(argc > 2 && !strcasecmp(argv[1], "reachable")) {
|
||||||
|
if(strcasecmp(argv[2], "nodes")) {
|
||||||
|
fprintf(stderr, "`reachable' only supported for nodes.\n");
|
||||||
|
usage(true);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
only_reachable = true;
|
||||||
|
argv++;
|
||||||
|
argc--;
|
||||||
|
}
|
||||||
|
|
||||||
if(argc != 2) {
|
if(argc != 2) {
|
||||||
fprintf(stderr, "Invalid number of arguments.\n");
|
fprintf(stderr, "Invalid number of arguments.\n");
|
||||||
usage(true);
|
usage(true);
|
||||||
|
@ -985,8 +999,10 @@ static int cmd_dump(int argc, char *argv[]) {
|
||||||
fprintf(stderr, "Unable to parse node dump from tincd: %s\n", line);
|
fprintf(stderr, "Unable to parse node dump from tincd: %s\n", line);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memcpy(&status, &status_int, sizeof status);
|
||||||
|
|
||||||
if(do_graph) {
|
if(do_graph) {
|
||||||
memcpy(&status, &status_int, sizeof status);
|
|
||||||
const char *color = "black";
|
const char *color = "black";
|
||||||
if(!strcmp(host, "MYSELF"))
|
if(!strcmp(host, "MYSELF"))
|
||||||
color = "green";
|
color = "green";
|
||||||
|
@ -1000,6 +1016,8 @@ static int cmd_dump(int argc, char *argv[]) {
|
||||||
color = "green";
|
color = "green";
|
||||||
printf(" %s [label = \"%s\", color = \"%s\"%s];\n", node, node, color, strcmp(host, "MYSELF") ? "" : ", style = \"filled\"");
|
printf(" %s [label = \"%s\", color = \"%s\"%s];\n", node, node, color, strcmp(host, "MYSELF") ? "" : ", style = \"filled\"");
|
||||||
} else {
|
} else {
|
||||||
|
if(only_reachable && !status.reachable)
|
||||||
|
continue;
|
||||||
printf("%s at %s port %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %hd (min %hd max %hd)\n",
|
printf("%s at %s port %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %hd (min %hd max %hd)\n",
|
||||||
node, host, port, cipher, digest, maclength, compression, options, status_int, nexthop, via, distance, pmtu, minmtu, maxmtu);
|
node, host, port, cipher, digest, maclength, compression, options, status_int, nexthop, via, distance, pmtu, minmtu, maxmtu);
|
||||||
}
|
}
|
||||||
|
@ -1233,6 +1251,7 @@ static struct {
|
||||||
} const variables[] = {
|
} const variables[] = {
|
||||||
/* Server configuration */
|
/* Server configuration */
|
||||||
{"AddressFamily", VAR_SERVER},
|
{"AddressFamily", VAR_SERVER},
|
||||||
|
{"AutoConnect", VAR_SERVER},
|
||||||
{"BindToAddress", VAR_SERVER | VAR_MULTIPLE},
|
{"BindToAddress", VAR_SERVER | VAR_MULTIPLE},
|
||||||
{"BindToInterface", VAR_SERVER},
|
{"BindToInterface", VAR_SERVER},
|
||||||
{"Broadcast", VAR_SERVER},
|
{"Broadcast", VAR_SERVER},
|
||||||
|
@ -1945,7 +1964,7 @@ static char *complete_command(const char *text, int state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *complete_dump(const char *text, int state) {
|
static char *complete_dump(const char *text, int state) {
|
||||||
const char *matches[] = {"nodes", "edges", "subnets", "connections", "graph", NULL};
|
const char *matches[] = {"reachable", "nodes", "edges", "subnets", "connections", "graph", NULL};
|
||||||
static int i;
|
static int i;
|
||||||
|
|
||||||
if(!state)
|
if(!state)
|
||||||
|
|
|
@ -450,11 +450,6 @@ int main2(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(!event_init()) {
|
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error initializing libevent!");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Setup sockets and open device. */
|
/* Setup sockets and open device. */
|
||||||
|
|
||||||
if(!setup_network())
|
if(!setup_network())
|
||||||
|
|
198
src/top.c
198
src/top.c
|
@ -57,11 +57,13 @@ static int sortmode = 0;
|
||||||
static bool cumulative = false;
|
static bool cumulative = false;
|
||||||
|
|
||||||
static list_t node_list;
|
static list_t node_list;
|
||||||
static struct timeval now, prev, diff;
|
static struct timeval cur, prev, diff;
|
||||||
static int delay = 1000;
|
static int delay = 1000;
|
||||||
static bool changed = true;
|
static bool changed = true;
|
||||||
static const char *unit = "bytes";
|
static const char *bunit = "bytes";
|
||||||
static float scale = 1;
|
static float bscale = 1;
|
||||||
|
static const char *punit = "pkts";
|
||||||
|
static float pscale = 1;
|
||||||
|
|
||||||
#ifndef timersub
|
#ifndef timersub
|
||||||
#define timersub(a, b, c) do {(c)->tv_sec = (a)->tv_sec - (b)->tv_sec; (c)->tv_usec = (a)->tv_usec = (b)->tv_usec;} while(0)
|
#define timersub(a, b, c) do {(c)->tv_sec = (a)->tv_sec - (b)->tv_sec; (c)->tv_usec = (a)->tv_usec = (b)->tv_usec;} while(0)
|
||||||
|
@ -69,10 +71,10 @@ static float scale = 1;
|
||||||
|
|
||||||
static void update(int fd) {
|
static void update(int fd) {
|
||||||
sendline(fd, "%d %d", CONTROL, REQ_DUMP_TRAFFIC);
|
sendline(fd, "%d %d", CONTROL, REQ_DUMP_TRAFFIC);
|
||||||
gettimeofday(&now, NULL);
|
gettimeofday(&cur, NULL);
|
||||||
|
|
||||||
timersub(&now, &prev, &diff);
|
timersub(&cur, &prev, &diff);
|
||||||
prev = now;
|
prev = cur;
|
||||||
float interval = diff.tv_sec + diff.tv_usec * 1e-6;
|
float interval = diff.tv_sec + diff.tv_usec * 1e-6;
|
||||||
|
|
||||||
char line[4096];
|
char line[4096];
|
||||||
|
@ -136,12 +138,69 @@ static void update(int fd) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cmpfloat(float a, float b) {
|
||||||
|
if(a < b)
|
||||||
|
return -1;
|
||||||
|
else if(a > b)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmpu64(uint64_t a, uint64_t b) {
|
||||||
|
if(a < b)
|
||||||
|
return -1;
|
||||||
|
else if(a > b)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sortfunc(const void *a, const void *b) {
|
||||||
|
const nodestats_t *na = *(const nodestats_t **)a;
|
||||||
|
const nodestats_t *nb = *(const nodestats_t **)b;
|
||||||
|
switch(sortmode) {
|
||||||
|
case 1:
|
||||||
|
if(cumulative)
|
||||||
|
return -cmpu64(na->in_packets, nb->in_packets) ?: na->i - nb->i;
|
||||||
|
else
|
||||||
|
return -cmpfloat(na->in_packets_rate, nb->in_packets_rate) ?: na->i - nb->i;
|
||||||
|
case 2:
|
||||||
|
if(cumulative)
|
||||||
|
return -cmpu64(na->in_bytes, nb->in_bytes) ?: na->i - nb->i;
|
||||||
|
else
|
||||||
|
return -cmpfloat(na->in_bytes_rate, nb->in_bytes_rate) ?: na->i - nb->i;
|
||||||
|
case 3:
|
||||||
|
if(cumulative)
|
||||||
|
return -cmpu64(na->out_packets, nb->out_packets) ?: na->i - nb->i;
|
||||||
|
else
|
||||||
|
return -cmpfloat(na->out_packets_rate, nb->out_packets_rate) ?: na->i - nb->i;
|
||||||
|
case 4:
|
||||||
|
if(cumulative)
|
||||||
|
return -cmpu64(na->out_bytes, nb->out_bytes) ?: na->i - nb->i;
|
||||||
|
else
|
||||||
|
return -cmpfloat(na->out_bytes_rate, nb->out_bytes_rate) ?: na->i - nb->i;
|
||||||
|
case 5:
|
||||||
|
if(cumulative)
|
||||||
|
return -cmpu64(na->in_packets + na->out_packets, nb->in_packets + nb->out_packets) ?: na->i - nb->i;
|
||||||
|
else
|
||||||
|
return -cmpfloat(na->in_packets_rate + na->out_packets_rate, nb->in_packets_rate + nb->out_packets_rate) ?: na->i - nb->i;
|
||||||
|
case 6:
|
||||||
|
if(cumulative)
|
||||||
|
return -cmpu64(na->in_bytes + na->out_bytes, nb->in_bytes + nb->out_bytes) ?: na->i - nb->i;
|
||||||
|
else
|
||||||
|
return -cmpfloat(na->in_bytes_rate + na->out_bytes_rate, nb->in_bytes_rate + nb->out_bytes_rate) ?: na->i - nb->i;
|
||||||
|
default:
|
||||||
|
return strcmp(na->name, nb->name) ?: na->i - nb->i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void redraw(void) {
|
static void redraw(void) {
|
||||||
erase();
|
erase();
|
||||||
|
|
||||||
mvprintw(0, 0, "Tinc %-16s Nodes: %4d Sort: %-10s %s", netname ?: "", node_list.count, sortname[sortmode], cumulative ? "Cumulative" : "Current");
|
mvprintw(0, 0, "Tinc %-16s Nodes: %4d Sort: %-10s %s", netname ?: "", node_list.count, sortname[sortmode], cumulative ? "Cumulative" : "Current");
|
||||||
attrset(A_REVERSE);
|
attrset(A_REVERSE);
|
||||||
mvprintw(2, 0, "Node IN pkts IN %s OUT pkts OUT %s", unit, unit);
|
mvprintw(2, 0, "Node IN %s IN %s OUT %s OUT %s", punit, bunit, punit, bunit);
|
||||||
chgat(-1, A_REVERSE, 0, NULL);
|
chgat(-1, A_REVERSE, 0, NULL);
|
||||||
|
|
||||||
static nodestats_t **sorted = 0;
|
static nodestats_t **sorted = 0;
|
||||||
|
@ -157,63 +216,6 @@ static void redraw(void) {
|
||||||
for(int i = 0; i < n; i++)
|
for(int i = 0; i < n; i++)
|
||||||
sorted[i]->i = i;
|
sorted[i]->i = i;
|
||||||
|
|
||||||
int cmpfloat(float a, float b) {
|
|
||||||
if(a < b)
|
|
||||||
return -1;
|
|
||||||
else if(a > b)
|
|
||||||
return 1;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cmpu64(uint64_t a, uint64_t b) {
|
|
||||||
if(a < b)
|
|
||||||
return -1;
|
|
||||||
else if(a > b)
|
|
||||||
return 1;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sortfunc(const void *a, const void *b) {
|
|
||||||
const nodestats_t *na = *(const nodestats_t **)a;
|
|
||||||
const nodestats_t *nb = *(const nodestats_t **)b;
|
|
||||||
switch(sortmode) {
|
|
||||||
case 1:
|
|
||||||
if(cumulative)
|
|
||||||
return -cmpu64(na->in_packets, nb->in_packets) ?: na->i - nb->i;
|
|
||||||
else
|
|
||||||
return -cmpfloat(na->in_packets_rate, nb->in_packets_rate) ?: na->i - nb->i;
|
|
||||||
case 2:
|
|
||||||
if(cumulative)
|
|
||||||
return -cmpu64(na->in_bytes, nb->in_bytes) ?: na->i - nb->i;
|
|
||||||
else
|
|
||||||
return -cmpfloat(na->in_bytes_rate, nb->in_bytes_rate) ?: na->i - nb->i;
|
|
||||||
case 3:
|
|
||||||
if(cumulative)
|
|
||||||
return -cmpu64(na->out_packets, nb->out_packets) ?: na->i - nb->i;
|
|
||||||
else
|
|
||||||
return -cmpfloat(na->out_packets_rate, nb->out_packets_rate) ?: na->i - nb->i;
|
|
||||||
case 4:
|
|
||||||
if(cumulative)
|
|
||||||
return -cmpu64(na->out_bytes, nb->out_bytes) ?: na->i - nb->i;
|
|
||||||
else
|
|
||||||
return -cmpfloat(na->out_bytes_rate, nb->out_bytes_rate) ?: na->i - nb->i;
|
|
||||||
case 5:
|
|
||||||
if(cumulative)
|
|
||||||
return -cmpu64(na->in_packets + na->out_packets, nb->in_packets + nb->out_packets) ?: na->i - nb->i;
|
|
||||||
else
|
|
||||||
return -cmpfloat(na->in_packets_rate + na->out_packets_rate, nb->in_packets_rate + nb->out_packets_rate) ?: na->i - nb->i;
|
|
||||||
case 6:
|
|
||||||
if(cumulative)
|
|
||||||
return -cmpu64(na->in_bytes + na->out_bytes, nb->in_bytes + nb->out_bytes) ?: na->i - nb->i;
|
|
||||||
else
|
|
||||||
return -cmpfloat(na->in_bytes_rate + na->out_bytes_rate, nb->in_bytes_rate + nb->out_bytes_rate) ?: na->i - nb->i;
|
|
||||||
default:
|
|
||||||
return strcmp(na->name, nb->name) ?: na->i - nb->i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
qsort(sorted, n, sizeof *sorted, sortfunc);
|
qsort(sorted, n, sizeof *sorted, sortfunc);
|
||||||
|
|
||||||
for(int i = 0, row = 3; i < n; i++, row++) {
|
for(int i = 0, row = 3; i < n; i++, row++) {
|
||||||
|
@ -228,10 +230,10 @@ static void redraw(void) {
|
||||||
|
|
||||||
if(cumulative)
|
if(cumulative)
|
||||||
mvprintw(row, 0, "%-16s %10"PRIu64" %10.0f %10"PRIu64" %10.0f",
|
mvprintw(row, 0, "%-16s %10"PRIu64" %10.0f %10"PRIu64" %10.0f",
|
||||||
node->name, node->in_packets, node->in_bytes * scale, node->out_packets, node->out_bytes * scale);
|
node->name, node->in_packets * pscale, node->in_bytes * bscale, node->out_packets * pscale, node->out_bytes * bscale);
|
||||||
else
|
else
|
||||||
mvprintw(row, 0, "%-16s %10.0f %10.0f %10.0f %10.0f",
|
mvprintw(row, 0, "%-16s %10.0f %10.0f %10.0f %10.0f",
|
||||||
node->name, node->in_packets_rate, node->in_bytes_rate * scale, node->out_packets_rate, node->out_bytes_rate * scale);
|
node->name, node->in_packets_rate * pscale, node->in_bytes_rate * bscale, node->out_packets_rate * pscale, node->out_bytes_rate * bscale);
|
||||||
}
|
}
|
||||||
|
|
||||||
attrset(A_NORMAL);
|
attrset(A_NORMAL);
|
||||||
|
@ -262,45 +264,53 @@ void top(int fd) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'c':
|
case 'c':
|
||||||
cumulative = !cumulative;
|
cumulative = !cumulative;
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
sortmode = 0;
|
sortmode = 0;
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
sortmode = 2;
|
sortmode = 2;
|
||||||
break;
|
break;
|
||||||
case 'I':
|
case 'I':
|
||||||
sortmode = 1;
|
sortmode = 1;
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
sortmode = 4;
|
sortmode = 4;
|
||||||
break;
|
break;
|
||||||
case 'O':
|
case 'O':
|
||||||
sortmode = 3;
|
sortmode = 3;
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
sortmode = 6;
|
sortmode = 6;
|
||||||
break;
|
break;
|
||||||
case 'T':
|
case 'T':
|
||||||
sortmode = 5;
|
sortmode = 5;
|
||||||
break;
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
unit = "bytes";
|
bunit = "bytes";
|
||||||
scale = 1;
|
bscale = 1;
|
||||||
break;
|
punit = "pkts";
|
||||||
|
pscale = 1;
|
||||||
|
break;
|
||||||
case 'k':
|
case 'k':
|
||||||
unit = "kbyte";
|
bunit = "kbyte";
|
||||||
scale = 1e-3;
|
bscale = 1e-3;
|
||||||
break;
|
punit = "pkts";
|
||||||
|
pscale = 1;
|
||||||
|
break;
|
||||||
case 'M':
|
case 'M':
|
||||||
unit = "Mbyte";
|
bunit = "Mbyte";
|
||||||
scale = 1e-6;
|
bscale = 1e-6;
|
||||||
break;
|
punit = "kpkt";
|
||||||
|
pscale = 1e-3;
|
||||||
|
break;
|
||||||
case 'G':
|
case 'G':
|
||||||
unit = "Gbyte";
|
bunit = "Gbyte";
|
||||||
scale = 1e-9;
|
bscale = 1e-9;
|
||||||
break;
|
punit = "Mpkt";
|
||||||
|
pscale = 1e-6;
|
||||||
|
break;
|
||||||
case 'q':
|
case 'q':
|
||||||
case KEY_BREAK:
|
case KEY_BREAK:
|
||||||
running = false;
|
running = false;
|
||||||
|
|
Loading…
Reference in a new issue