Import Debian changes 1.1~pre4-1
tinc (1.1~pre4-1) experimental; urgency=low [ Gian Piero ] * Allow resource limits to be set in /etc/default/tinc. Closes: #690685 [ Guus Sliepen ] * New upstream release.
This commit is contained in:
commit
e9142bd3a6
52 changed files with 1797 additions and 1177 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
|
||||
Author: Guus Sliepen <guus@tinc-vpn.org>
|
||||
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
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
|
||||
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libevent.m4 \
|
||||
$(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \
|
||||
$(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \
|
||||
$(top_srcdir)/configure.in
|
||||
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/lzo.m4 \
|
||||
$(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \
|
||||
$(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.in
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
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
|
||||
|
||||
* 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
|
||||
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.
|
||||
|
||||
|
@ -262,347 +276,354 @@ version 1.0.5 Nov 14 2006
|
|||
|
||||
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.
|
||||
|
||||
* 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
|
||||
anything on tap devices as long as the underlying OS supports it.
|
||||
* 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.
|
||||
|
||||
* 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
|
||||
cryptographic functions,
|
||||
* Strict checks for length incoming network packets and return values of
|
||||
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
|
||||
environment.
|
||||
* Added support for Windows 2000 and XP, both natively and in a Cygwin
|
||||
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
|
||||
conditions and improve scalability.
|
||||
* Switched from undirected graphs to directed graphs to avoid certain race
|
||||
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
|
||||
keys are bad.
|
||||
* Fix handling of subnets when prefixlength isn't divisible by 8.
|
||||
|
||||
* 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,
|
||||
FreeBSD, possibly OpenBSD but not on Solaris.
|
||||
Version 1.0pre5 Feb 9 2002
|
||||
|
||||
* Support for tunnels over IPv6 networks. Works on all supported
|
||||
operating systems.
|
||||
* Security enhancements:
|
||||
* 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
|
||||
the packets.
|
||||
* Some internal changes to make tinc scale better for large
|
||||
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
|
||||
configuration as it is.
|
||||
* Further, thanks to Enrique Zanardi, we have Spanish messages; Matias
|
||||
Carrasco provided us with a Spanish translation of the manual.
|
||||
|
||||
* Some internal changes to make tinc scale better for large
|
||||
networks, such as using AVL trees instead of linked lists for the
|
||||
connection list.
|
||||
Version 1.0pre2 May 31 2000
|
||||
|
||||
* RSA keys can be stored in separate files if needed. See the
|
||||
documentation for more information.
|
||||
* This version has been internationalized; and a Dutch translation has
|
||||
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
|
||||
still under discussion, this is secure. Care has been taken to
|
||||
resist most, if not all, attacks.
|
||||
* 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.
|
||||
|
||||
* 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.
|
||||
Version 1.0pre1 May 12 2000
|
||||
|
||||
* 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
|
||||
|
||||
* Various other bugfixes
|
||||
|
||||
* Documentation updates
|
||||
|
||||
version 0.3.3 Feb 9 2000
|
||||
* Fixed bug that made tinc stop working with latest kernels (Guus
|
||||
Sliepen)
|
||||
Version 0.3.3 Feb 9 2000
|
||||
|
||||
* Fixed bug that made tinc stop working with latest kernels
|
||||
|
||||
* Updated the manual
|
||||
|
||||
version 0.3.2 Nov 12 1999
|
||||
* no more `Invalid filedescriptor' when working with multiple
|
||||
connections
|
||||
* forward unknown packets to uplink
|
||||
Version 0.3.2 Nov 12 1999
|
||||
|
||||
version 0.3.1 Oct 20 1999
|
||||
* fixed a bug where tinc would exit without a trace
|
||||
* No more `Invalid filedescriptor' when working with multiple
|
||||
connections.
|
||||
|
||||
version 0.3 Aug 20 1999
|
||||
* pings now work immediately
|
||||
* all packet sizes get transmitted correctly
|
||||
* Forward unknown packets to uplink.
|
||||
|
||||
version 0.2.26 Aug 15 1999
|
||||
* fixed some remaining bugs
|
||||
* --sysconfdir works with configure
|
||||
* last version before 0.3
|
||||
Version 0.3.1 Oct 20 1999
|
||||
|
||||
version 0.2.25 Aug 8 1999
|
||||
* improved stability, going towards 0.3 now.
|
||||
* Fixed a bug where tinc would exit without a trace.
|
||||
|
||||
version 0.2.24 Aug 7 1999
|
||||
* added key aging, there's a new config variable, KeyExpire.
|
||||
* updated man and info pages
|
||||
Version 0.3 Aug 20 1999
|
||||
|
||||
version 0.2.23 Aug 5 1999
|
||||
* all known bugs fixed, this is a candidate for 0.3
|
||||
* Pings now work immediately.
|
||||
|
||||
version 0.2.22 Apr 11 1999
|
||||
* multiconnection thing is now working nearly perfect :)
|
||||
* All packet sizes get transmitted correctly.
|
||||
|
||||
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
|
||||
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
|
||||
* blowfish library dynamically loaded upon execution
|
||||
* included Eric Young's IDEA library
|
||||
Version 0.2.18 Apr 3 1999
|
||||
|
||||
version 0.2.17 Apr 1 1999
|
||||
* tincd now re-executes itself in case of a segmentation fault.
|
||||
* Blowfish library dynamically loaded upon execution.
|
||||
|
||||
version 0.2.16 Apr 1 1999
|
||||
* 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.
|
||||
* Included Eric Young's IDEA library.
|
||||
|
||||
version 0.2.15 Mar 29 1999
|
||||
* fixed bugs
|
||||
Version 0.2.17 Apr 1 1999
|
||||
|
||||
version 0.2.14 Feb 10 1999
|
||||
* added --timeout flag and PingTimeout configuration
|
||||
* did some first syslog cleanup work
|
||||
* Tincd now re-executes itself in case of a segmentation fault.
|
||||
|
||||
version 0.2.13 Jan 23 1999
|
||||
* bugfixes
|
||||
Version 0.2.16 Apr 1 1999
|
||||
|
||||
version 0.2.12 Jan 23 1999
|
||||
* fixed nauseating bug so that it would crash whenever a connection
|
||||
got lost
|
||||
* Wrote tincd.conf(5) man page, which still needs a lot of work.
|
||||
|
||||
version 0.2.11 Jan 22 1999
|
||||
* framework for multiple connections has been done
|
||||
* simple manpage for tincd
|
||||
* 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.10 Jan 18 1999
|
||||
* passphrase support added
|
||||
Version 0.2.15 Mar 29 1999
|
||||
|
||||
version 0.2.9 Jan 13 1999
|
||||
* bugs fixed.
|
||||
* Fixed bugs.
|
||||
|
||||
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.14 Feb 10 1999
|
||||
|
||||
version 0.2.7 Jan 3 1999
|
||||
* several updates to make extending more easy.
|
||||
* Added --timeout flag and PingTimeout configuration.
|
||||
* 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
|
||||
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.
|
||||
|
||||
version 0.2.4 Dec 16 1998
|
||||
* now it really does ;)
|
||||
Version 0.2.4 Dec 16 1998
|
||||
|
||||
version 0.2.3 Nov 24 1998
|
||||
* it sort of works now
|
||||
* Now it really does ;)
|
||||
|
||||
version 0.2.2 Nov 20 1998
|
||||
* uses GNU gmp.
|
||||
Version 0.2.3 Nov 24 1998
|
||||
|
||||
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.
|
||||
|
|
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.
|
||||
|
||||
tinc is Copyright (C) 1998-2012 by:
|
||||
|
@ -36,11 +36,11 @@ at your own risk.
|
|||
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.
|
||||
|
||||
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
|
||||
|
@ -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:
|
||||
|
||||
- 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:
|
||||
|
||||
|
|
1
aclocal.m4
vendored
1
aclocal.m4
vendored
|
@ -1135,7 +1135,6 @@ AC_SUBST([am__untar])
|
|||
|
||||
m4_include([m4/attribute.m4])
|
||||
m4_include([m4/curses.m4])
|
||||
m4_include([m4/libevent.m4])
|
||||
m4_include([m4/lzo.m4])
|
||||
m4_include([m4/openssl.m4])
|
||||
m4_include([m4/readline.m4])
|
||||
|
|
|
@ -64,9 +64,6 @@
|
|||
/* Define to 1 if you have the `ECDSA_verify' function. */
|
||||
#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. */
|
||||
#undef HAVE_EVP_ENCRYPTINIT_EX
|
||||
|
||||
|
|
112
configure
vendored
112
configure
vendored
|
@ -738,7 +738,6 @@ enable_uml
|
|||
enable_vde
|
||||
enable_tunemu
|
||||
with_windows2000
|
||||
with_libgcrypt
|
||||
enable_curses
|
||||
with_curses
|
||||
with_curses_include
|
||||
|
@ -747,9 +746,6 @@ enable_readline
|
|||
with_readline
|
||||
with_readline_include
|
||||
with_readline_lib
|
||||
with_libevent
|
||||
with_libevent_include
|
||||
with_libevent_lib
|
||||
enable_zlib
|
||||
with_zlib
|
||||
with_zlib_include
|
||||
|
@ -1393,9 +1389,9 @@ Optional Features:
|
|||
--enable-dependency-tracking do not reject slow dependency extractors
|
||||
--enable-maintainer-mode enable make rules and dependencies not useful
|
||||
(and sometimes confusing) to the casual installer
|
||||
--disable-uml enable support for User Mode Linux
|
||||
--disable-vde enable support for Virtual Distributed Ethernet
|
||||
--disable-tunemu enable support for the tunemu driver
|
||||
--enable-uml enable support for User Mode Linux
|
||||
--enable-vde enable support for Virtual Distributed Ethernet
|
||||
--enable-tunemu enable support for the tunemu driver
|
||||
--disable-curses disable curses support
|
||||
--disable-readline disable readline 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-windows2000 compile with support for Windows 2000. This disables
|
||||
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-include=DIR
|
||||
curses headers directory
|
||||
|
@ -1417,10 +1412,6 @@ Optional Packages:
|
|||
--with-readline-include=DIR
|
||||
readline headers 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-include=DIR zlib headers directory
|
||||
--with-zlib-lib=DIR zlib library directory
|
||||
|
@ -4104,7 +4095,7 @@ fi
|
|||
|
||||
# Define the identity of the package.
|
||||
PACKAGE=tinc
|
||||
VERSION=1.1pre3
|
||||
VERSION=1.1pre4
|
||||
|
||||
|
||||
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.
|
||||
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.
|
||||
if test "${enable_zlib+set}" = set; then :
|
||||
enableval=$enable_zlib;
|
||||
|
|
11
configure.in
11
configure.in
|
@ -4,7 +4,7 @@ AC_PREREQ(2.61)
|
|||
AC_INIT
|
||||
AC_CONFIG_SRCDIR([src/tincd.c])
|
||||
AC_GNU_SOURCE
|
||||
AM_INIT_AUTOMAKE(tinc, 1.1pre3)
|
||||
AM_INIT_AUTOMAKE(tinc, 1.1pre4)
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
|
@ -74,7 +74,7 @@ case $host_os in
|
|||
esac
|
||||
|
||||
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"],
|
||||
[ AC_DEFINE(ENABLE_UML, 1, [Support for UML])
|
||||
uml=true
|
||||
|
@ -85,7 +85,7 @@ AC_ARG_ENABLE(uml,
|
|||
)
|
||||
|
||||
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"],
|
||||
[ AC_CHECK_HEADERS(libvdeplug_dyn.h, [], [AC_MSG_ERROR([VDE plug header files not found.]); break])
|
||||
AC_DEFINE(ENABLE_VDE, 1, [Support for VDE])
|
||||
|
@ -97,7 +97,7 @@ AC_ARG_ENABLE(vde,
|
|||
)
|
||||
|
||||
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"],
|
||||
[ AC_DEFINE(ENABLE_TUNEMU, 1, [Support for tunemu])
|
||||
tunemu=true
|
||||
|
@ -179,11 +179,10 @@ AC_CACHE_SAVE
|
|||
|
||||
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_READLINE
|
||||
tinc_LIBEVENT
|
||||
tinc_ZLIB
|
||||
tinc_LZO
|
||||
|
||||
|
|
38
debian/changelog
vendored
38
debian/changelog
vendored
|
@ -1,3 +1,13 @@
|
|||
tinc (1.1~pre4-1) experimental; urgency=low
|
||||
|
||||
[ Gian Piero ]
|
||||
* Allow resource limits to be set in /etc/default/tinc. Closes: #690685
|
||||
|
||||
[ Guus Sliepen ]
|
||||
* New upstream release.
|
||||
|
||||
-- Guus Sliepen <guus@debian.org> Wed, 05 Dec 2012 23:05:01 +0100
|
||||
|
||||
tinc (1.1~pre3-1) experimental; urgency=low
|
||||
|
||||
* New upstream release.
|
||||
|
@ -26,6 +36,34 @@ tinc (1.1~pre2-1) experimental; urgency=low
|
|||
|
||||
-- Michael Tokarev <mjt@tls.msk.ru> Sun, 07 Aug 2011 12:57:15 +0400
|
||||
|
||||
tinc (1.0.19-2) unstable; urgency=low
|
||||
|
||||
* Fix behaviour of tinc-pidfile. Closes: #679130
|
||||
* Enable parallel building in debian/rules.
|
||||
|
||||
-- Guus Sliepen <guus@debian.org> Tue, 26 Jun 2012 18:28:34 +0200
|
||||
|
||||
tinc (1.0.19-1) unstable; urgency=low
|
||||
|
||||
* New upstream release.
|
||||
* Bump debian/compat so tinc gets built with hardening flags.
|
||||
* Allow tinc-pidfile in /etc/network/interfaces.
|
||||
|
||||
-- Guus Sliepen <guus@debian.org> Mon, 25 Jun 2012 20:29:22 +0200
|
||||
|
||||
tinc (1.0.18-1) unstable; urgency=low
|
||||
|
||||
* New upstream release.
|
||||
|
||||
-- Guus Sliepen <guus@debian.org> Sun, 25 Mar 2012 18:52:15 +0200
|
||||
|
||||
tinc (1.0.17-1) unstable; urgency=low
|
||||
|
||||
* New upstream release.
|
||||
* Enable support for UML and VDE.
|
||||
|
||||
-- Guus Sliepen <guus@debian.org> Sat, 10 Mar 2012 14:50:00 +0100
|
||||
|
||||
tinc (1.0.16-1) unstable; urgency=low
|
||||
|
||||
* New upstream release.
|
||||
|
|
2
debian/control
vendored
2
debian/control
vendored
|
@ -3,7 +3,7 @@ Section: net
|
|||
Priority: optional
|
||||
Maintainer: Guus Sliepen <guus@debian.org>
|
||||
Standards-Version: 3.9.3
|
||||
Build-Depends: libssl-dev (>>1.0.0), debhelper (>= 9), texi2html, texinfo, zlib1g-dev, liblzo2-dev, libncurses5-dev, libevent-dev, libreadline-dev
|
||||
Build-Depends: libssl-dev (>>1.0.0), debhelper (>= 9), texi2html, texinfo, zlib1g-dev, liblzo2-dev, libncurses5-dev, libreadline-dev
|
||||
Homepage: http://www.tinc-vpn.org/
|
||||
|
||||
Package: tinc
|
||||
|
|
5
debian/tinc.default
vendored
5
debian/tinc.default
vendored
|
@ -1,2 +1,7 @@
|
|||
# Extra options to be passed to tincd.
|
||||
# EXTRA="-d"
|
||||
|
||||
# Limits to be configured for the tincd process. Please read your shell
|
||||
# (pointed by /bin/sh) documentation for ulimit. You probably want to raise the
|
||||
# max locked memory value if using both --mlock and --user flags.
|
||||
# LIMITS="-l 128"
|
||||
|
|
14
debian/tinc.init
vendored
14
debian/tinc.init
vendored
|
@ -58,6 +58,20 @@ signal_running() {
|
|||
done
|
||||
}
|
||||
|
||||
setlimits() {
|
||||
while [ $# -gt 0 ]; do
|
||||
parm=$1 ; shift
|
||||
if [ -n "$1" -a "${1#-}" = "$1" ]; then
|
||||
value=$1 ; shift
|
||||
ulimit $parm $value
|
||||
else
|
||||
ulimit $parm
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
test -n "$LIMITS" && setlimits $LIMITS
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
foreach_net "Starting $DESC:" start
|
||||
|
|
|
@ -53,10 +53,9 @@ subdir = doc
|
|||
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in texinfo.tex
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
|
||||
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libevent.m4 \
|
||||
$(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \
|
||||
$(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \
|
||||
$(top_srcdir)/configure.in
|
||||
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/lzo.m4 \
|
||||
$(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \
|
||||
$(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.in
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
mkinstalldirs = $(install_sh) -d
|
||||
|
|
Binary file not shown.
|
@ -3,16 +3,13 @@
|
|||
.\" Manual page created by:
|
||||
.\" Ivo Timmermans
|
||||
.\" Guus Sliepen <guus@tinc-vpn.org>
|
||||
|
||||
.Sh NAME
|
||||
.Nm tinc.conf
|
||||
.Nd tinc daemon configuration
|
||||
|
||||
.Sh DESCRIPTION
|
||||
The files in the
|
||||
.Pa @sysconfdir@/tinc/
|
||||
directory contain runtime and security information for the tinc daemon.
|
||||
|
||||
.Sh NETWORKS
|
||||
To distinguish multiple instances of tinc running on one computer,
|
||||
you can use the
|
||||
|
@ -44,31 +41,26 @@ the configuration file should be
|
|||
.Pa @sysconfdir@/tinc/tinc.conf ,
|
||||
and the host configuration files are now expected to be in
|
||||
.Pa @sysconfdir@/tinc/hosts/ .
|
||||
|
||||
.Sh NAMES
|
||||
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 has to be declared in the
|
||||
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf
|
||||
file.
|
||||
|
||||
.Pp
|
||||
To make things easy,
|
||||
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.
|
||||
However, you are only allowed to use alphanumerical characters (a-z, A-Z, and 0-9) and underscores (_) in the name.
|
||||
|
||||
.Sh INITIAL CONFIGURATION
|
||||
If you have not configured tinc yet, you can easily create a basic configuration using the following command:
|
||||
.Bd -literal -offset indent
|
||||
.Nm tincctl Fl n Ar NETNAME Li init Ar NAME
|
||||
.Ed
|
||||
|
||||
.Pp
|
||||
You can further change the configuration as needed either by manually editing the configuration files,
|
||||
or by using
|
||||
.Xr tincctl 8 .
|
||||
|
||||
.Sh PUBLIC/PRIVATE KEYS
|
||||
The
|
||||
.Nm tincctl Li init
|
||||
|
@ -81,24 +73,20 @@ in the directory
|
|||
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /
|
||||
The public keys should be stored in the host configuration file
|
||||
.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.
|
||||
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:
|
||||
.Bd -literal -offset indent
|
||||
.Nm tincctl Fl n Ar NETNAME Li generate-ecdsa-keys
|
||||
.Ed
|
||||
|
||||
.Sh SERVER CONFIGURATION
|
||||
The server configuration of the daemon is done in the file
|
||||
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf .
|
||||
This file consists of comments (lines started with a
|
||||
.Li # )
|
||||
or assignments in the form of:
|
||||
|
||||
.Pp
|
||||
.Va Variable Li = Ar Value .
|
||||
|
||||
.Pp
|
||||
The variable names are case insensitive, and any spaces, tabs,
|
||||
newlines and carriage returns are ignored.
|
||||
|
@ -106,31 +94,35 @@ Note: it is not required that you put in the
|
|||
.Li =
|
||||
sign, but doing so improves readability.
|
||||
If you leave it out, remember to replace it with at least one space character.
|
||||
|
||||
.Pp
|
||||
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
|
||||
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf ,
|
||||
it is recommended to put host specific configuration options in the host configuration file,
|
||||
as this makes it easy to exchange with other nodes.
|
||||
|
||||
.Pp
|
||||
You can edit the config file manually, but it is recommended that you use
|
||||
.Xr tincctl 8
|
||||
to change configuration variables for you.
|
||||
|
||||
.Pp
|
||||
Here are all valid variables, listed in alphabetical order.
|
||||
The default value is given between parentheses.
|
||||
.Bl -tag -width indent
|
||||
|
||||
.It Va AddressFamily Li = ipv4 | ipv6 | any Pq any
|
||||
This option affects the address family of listening and outgoing sockets.
|
||||
If
|
||||
.Qq any
|
||||
is selected, then depending on the operating system both IPv4 and IPv6 or just
|
||||
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
|
||||
If your computer has more than one IPv4 or IPv6 address,
|
||||
.Nm tinc
|
||||
|
@ -149,38 +141,31 @@ To only bind to a specific port but not to a specific address, use
|
|||
.Li *
|
||||
for the
|
||||
.Ar address .
|
||||
|
||||
.It Va BindToInterface Li = Ar interface Bq experimental
|
||||
If your computer has more than one network interface,
|
||||
.Nm tinc
|
||||
will by default listen on all of them for incoming connections.
|
||||
It is possible to bind only to a single interface with this variable.
|
||||
|
||||
.Pp
|
||||
This option may not work on all platforms.
|
||||
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.
|
||||
|
||||
.It Va Broadcast Li = no | mst | direct Po mst Pc Bq experimental
|
||||
This option selects the way broadcast packets are sent to other daemons.
|
||||
NOTE: all nodes in a VPN must use the same
|
||||
.Va Broadcast
|
||||
mode, otherwise routing loops can form.
|
||||
|
||||
.Bl -tag -width indent
|
||||
.It no
|
||||
Broadcast packets are never sent to other nodes.
|
||||
|
||||
.It mst
|
||||
Broadcast packets are sent and forwarded via the VPN's Minimum Spanning Tree.
|
||||
This ensures broadcast packets reach all nodes.
|
||||
|
||||
.It direct
|
||||
Broadcast packets are sent directly to all nodes that can be reached directly.
|
||||
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.
|
||||
.El
|
||||
|
||||
.It Va ConnectTo Li = Ar name
|
||||
Specifies which other tinc daemon to connect to on startup.
|
||||
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
|
||||
.Va ConnectTo
|
||||
line).
|
||||
|
||||
.Pp
|
||||
If you don't specify a host with
|
||||
.Va ConnectTo ,
|
||||
.Nm tinc
|
||||
won't try to connect to other daemons at all,
|
||||
and will instead just listen for incoming connections.
|
||||
|
||||
.It Va DecrementTTL Li = yes | no Po no Pc Bq experimental
|
||||
When enabled,
|
||||
.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.
|
||||
.Pp
|
||||
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
|
||||
The virtual network device to use.
|
||||
.Nm tinc
|
||||
|
@ -220,18 +202,15 @@ instead of
|
|||
.Va Device .
|
||||
The info pages of the tinc package contain more information
|
||||
about configuring the virtual network device.
|
||||
|
||||
.It Va DeviceType Li = Ar type Pq platform dependent
|
||||
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.
|
||||
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
|
||||
|
||||
.It dummy
|
||||
Use a dummy interface.
|
||||
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.
|
||||
|
||||
.It raw_socket
|
||||
Open a raw socket, and bind it to a pre-existing
|
||||
.Va Interface
|
||||
|
@ -239,7 +218,6 @@ Open a raw socket, and bind it to a pre-existing
|
|||
All packets are read from this interface.
|
||||
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.
|
||||
|
||||
.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
|
||||
.Va Device .
|
||||
|
@ -249,7 +227,6 @@ Do NOT connect multiple
|
|||
.Nm tinc
|
||||
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.
|
||||
|
||||
.It uml Pq not compiled in by default
|
||||
Create a UNIX socket with the filename specified by
|
||||
.Va Device ,
|
||||
|
@ -258,7 +235,6 @@ or
|
|||
if not specified.
|
||||
.Nm tinc
|
||||
will wait for a User Mode Linux instance to connect to this socket.
|
||||
|
||||
.It vde Pq not compiled in by default
|
||||
Uses the libvdeplug library to connect to a Virtual Distributed Ethernet switch,
|
||||
using the UNIX socket specified by
|
||||
|
@ -267,46 +243,37 @@ or
|
|||
.Pa @localstatedir@/run/vde.ctl
|
||||
if not specified.
|
||||
.El
|
||||
|
||||
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:
|
||||
|
||||
.Bl -tag -width indent
|
||||
|
||||
.It tun Pq BSD and Linux
|
||||
Set type to tun.
|
||||
Depending on the platform, this can either be with or without an address family header (see below).
|
||||
|
||||
.It tunnohead Pq BSD
|
||||
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.
|
||||
On some platforms IPv6 packets cannot be read from or written to the device in this mode.
|
||||
|
||||
.It tunifhead Pq BSD
|
||||
Set type to tun with an address family header.
|
||||
Tinc will expect packets read from the virtual network device
|
||||
to start with a four byte header containing the address family,
|
||||
followed by an IP header.
|
||||
This mode should support both IPv4 and IPv6 packets.
|
||||
|
||||
.It tap Pq BSD and Linux
|
||||
Set type to tap.
|
||||
Tinc will expect packets read from the virtual network device
|
||||
to start with an Ethernet header.
|
||||
.El
|
||||
|
||||
.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,
|
||||
but which would have to be forwarded by an intermediate node, are dropped instead.
|
||||
When combined with the IndirectData option,
|
||||
packets for nodes for which we do not have a meta connection with are also dropped.
|
||||
|
||||
.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.
|
||||
This is only used if
|
||||
.Va ExperimentalProtocol
|
||||
is enabled.
|
||||
|
||||
.It Va ExperimentalProtocol Li = yes | no Po no Pc Bq experimental
|
||||
When this option is enabled, experimental protocol enhancements will be used.
|
||||
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 .
|
||||
The experimental protocol may change at any time,
|
||||
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
|
||||
This option selects the way indirect packets are forwarded.
|
||||
.Bl -tag -width indent
|
||||
|
||||
.It off
|
||||
Incoming packets that are not meant for the local node,
|
||||
but which should be forwarded to another node, are dropped.
|
||||
|
||||
.It internal
|
||||
Incoming packets that are meant for another node are forwarded by tinc internally.
|
||||
|
||||
.Pp
|
||||
This is the default mode, and unless you really know you need another forwarding mode, don't change it.
|
||||
|
||||
.It kernel
|
||||
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,
|
||||
and can also help debugging.
|
||||
.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
|
||||
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
|
||||
efficiency, even stopping the daemon for a few seconds every time it does
|
||||
a lookup if your DNS server is not responding.
|
||||
|
||||
.Pp
|
||||
This does not affect resolving hostnames to IP addresses from the
|
||||
host configuration files, but whether hostnames should be resolved while logging.
|
||||
|
||||
.It Va IffOneQueue Li = yes | no Po no Pc Bq experimental
|
||||
(Linux only) Set IFF_ONE_QUEUE flag on TUN/TAP devices.
|
||||
|
||||
.It Va Interface Li = Ar interface
|
||||
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.
|
||||
|
@ -369,12 +314,10 @@ Under Windows, this variable is used to select which network interface will be u
|
|||
If you specified a
|
||||
.Va Device ,
|
||||
this variable is almost always already correctly set.
|
||||
|
||||
.It Va KeyExpire Li = Ar seconds Pq 3600
|
||||
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,
|
||||
even though it is thought to be nearly impossible to crack a single key.
|
||||
|
||||
.It Va LocalDiscovery Li = yes | no Pq no
|
||||
When enabled,
|
||||
.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
|
||||
and they only ConnectTo a third node outside the NAT,
|
||||
which normally would prevent the peers from learning each other's LAN address.
|
||||
|
||||
.Pp
|
||||
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.
|
||||
|
||||
.It Va MACExpire Li = Ar seconds Pq 600
|
||||
This option controls the amount of time MAC addresses are kept before they are removed.
|
||||
This only has effect when
|
||||
.Va Mode
|
||||
is set to
|
||||
.Qq switch .
|
||||
|
||||
.It Va MaxTimeout Li = Ar seconds Pq 900
|
||||
This is the maximum delay before trying to reconnect to other tinc daemons.
|
||||
|
||||
.It Va Mode Li = router | switch | hub Pq router
|
||||
This option selects the way packets are routed to other daemons.
|
||||
.Bl -tag -width indent
|
||||
|
||||
.It router
|
||||
In this mode
|
||||
.Va Subnet
|
||||
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.
|
||||
|
||||
.Pp
|
||||
This is the default mode, and unless you really know you need another mode, don't change it.
|
||||
|
||||
.It switch
|
||||
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.
|
||||
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.
|
||||
|
||||
.Pp
|
||||
This mode is primarily useful if you want to bridge Ethernet segments.
|
||||
|
||||
.It hub
|
||||
This mode is almost the same as the switch mode, but instead
|
||||
every packet will be broadcast to the other daemons
|
||||
while no routing table is managed.
|
||||
.El
|
||||
|
||||
.It Va Name Li = Ar name Bq required
|
||||
This is the name which identifies this tinc daemon.
|
||||
It must be unique for the virtual private network this daemon will connect to.
|
||||
The Name may only consist of alphanumeric and underscore characters.
|
||||
|
||||
If
|
||||
.Va Name
|
||||
starts with a
|
||||
|
@ -441,40 +373,28 @@ If
|
|||
is
|
||||
.Li $HOST ,
|
||||
but no such environment variable exist, the hostname will be read using the gethostnname() system call.
|
||||
|
||||
.It Va PingInterval Li = Ar seconds Pq 60
|
||||
The number of seconds of inactivity that
|
||||
.Nm tinc
|
||||
will wait before sending a probe to the other end.
|
||||
|
||||
.It Va PingTimeout Li = Ar seconds Pq 5
|
||||
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,
|
||||
the connection is terminated,
|
||||
and the others will be notified of this.
|
||||
|
||||
.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
|
||||
will be inherited by the UDP packets that are sent out.
|
||||
|
||||
.It Va PrivateKey Li = Ar key Bq obsolete
|
||||
The private RSA key of this tinc daemon.
|
||||
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
|
||||
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
|
||||
When this option is used the priority of the
|
||||
.Nm tincd
|
||||
process will be adjusted.
|
||||
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
|
||||
Use a proxy when making outgoing connections.
|
||||
The following proxy types are currently supported:
|
||||
|
@ -507,7 +427,6 @@ and
|
|||
.Ev REMOTEPORT
|
||||
are available.
|
||||
.El
|
||||
|
||||
.It Va ReplayWindow Li = Ar bytes Pq 16
|
||||
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
|
||||
|
@ -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
|
||||
pass all traffic, but leaves tinc vulnerable to replay-based attacks on your
|
||||
traffic.
|
||||
|
||||
.It Va StrictSubnets Li = yes | no Po no Pc Bq experimental
|
||||
When this option is enabled tinc will only use Subnet statements which are
|
||||
present in the host config files in the local
|
||||
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/
|
||||
directory.
|
||||
|
||||
.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,
|
||||
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/
|
||||
directory.
|
||||
Setting this options also implicitly sets StrictSubnets.
|
||||
|
||||
.It Va UDPRcvBuf Li = Ar bytes Pq OS default
|
||||
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.
|
||||
|
||||
.It Va UDPSndBuf Li = Ar bytes Pq OS default
|
||||
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.
|
||||
.El
|
||||
|
||||
.Sh HOST CONFIGURATION FILES
|
||||
The host configuration files contain all information needed
|
||||
to establish a connection to those hosts.
|
||||
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.
|
||||
|
||||
.Pp
|
||||
The idea is that these files are portable.
|
||||
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,
|
||||
no secrets are revealed by sending out this information.
|
||||
.Bl -tag -width indent
|
||||
|
||||
.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.
|
||||
This will only be used when trying to make an outgoing connection to this tinc daemon.
|
||||
|
@ -563,7 +475,6 @@ Multiple
|
|||
.Va Address
|
||||
variables can be specified, in which case each address will be tried until a working
|
||||
connection has been established.
|
||||
|
||||
.It Va Cipher Li = Ar cipher Pq blowfish
|
||||
The symmetric cipher algorithm used to encrypt UDP packets.
|
||||
Any cipher supported by OpenSSL is recognised.
|
||||
|
@ -571,24 +482,20 @@ Furthermore, specifying
|
|||
.Qq none
|
||||
will turn off packet encryption.
|
||||
It is best to use only those ciphers which support CBC mode.
|
||||
|
||||
.It Va ClampMSS Li = yes | no Pq yes
|
||||
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
|
||||
Fragmentation Needed or Packet too Big messages are dropped by firewalls.
|
||||
|
||||
.It Va Compression Li = Ar level Pq 0
|
||||
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),
|
||||
10 (fast lzo) and 11 (best lzo).
|
||||
|
||||
.It Va Digest Li = Ar digest Pq sha1
|
||||
The digest algorithm used to authenticate UDP packets.
|
||||
Any digest supported by OpenSSL is recognised.
|
||||
Furthermore, specifying
|
||||
.Qq none
|
||||
will turn off packet authentication.
|
||||
|
||||
.It Va IndirectData Li = yes | no Pq no
|
||||
This option specifies whether other tinc daemons besides the one you specified with
|
||||
.Va ConnectTo
|
||||
|
@ -596,33 +503,26 @@ can make a direct connection to you.
|
|||
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.
|
||||
Otherwise, it is best to leave this option out or set it to no.
|
||||
|
||||
.It Va MACLength Li = Ar length Pq 4
|
||||
The length of the message authentication code used to authenticate UDP packets.
|
||||
Can be anything from
|
||||
.Qq 0
|
||||
up to the length of the digest produced by the digest algorithm.
|
||||
|
||||
.It Va PMTU Li = Ar mtu Po 1514 Pc
|
||||
This option controls the initial path MTU to this node.
|
||||
|
||||
.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.
|
||||
After the path MTU has been discovered, it will be enforced on the VPN.
|
||||
|
||||
.It Va Port Li = Ar port Pq 655
|
||||
The port number on which this tinc daemon is listening for incoming connections,
|
||||
which is used if no port number is specified in an
|
||||
.Va Address
|
||||
statement.
|
||||
|
||||
.It Va PublicKey Li = Ar key Bq obsolete
|
||||
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 Va PublicKeyFile Li = Ar filename Bq obsolete
|
||||
The file in which the public RSA key of this tinc daemon resides.
|
||||
|
||||
.Pp
|
||||
From version 1.0pre4 on
|
||||
.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
|
||||
in each host configuration file,
|
||||
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
|
||||
The subnet which this tinc daemon will serve.
|
||||
.Nm tinc
|
||||
|
@ -641,7 +540,6 @@ it will be sent to the daemon who has this subnet in his host configuration file
|
|||
Multiple
|
||||
.Va Subnet
|
||||
variables can be specified.
|
||||
|
||||
.Pp
|
||||
Subnets can either be single MAC, IPv4 or IPv6 addresses,
|
||||
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.
|
||||
IPv6 subnets are notated like fec0:0:0:1::/64.
|
||||
MAC addresses are notated like 0:1a:2b:3c:4d:5e.
|
||||
|
||||
.Pp
|
||||
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
|
||||
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
|
||||
priority will be tried, and so on.
|
||||
|
||||
.It Va TCPOnly Li = yes | no Pq no Bq obsolete
|
||||
If this variable is set to yes,
|
||||
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,
|
||||
or if UDP packet routing is disabled somehow.
|
||||
Setting this options also implicitly sets IndirectData.
|
||||
|
||||
.Pp
|
||||
Since version 1.0.10, tinc will automatically detect whether communication via
|
||||
UDP is possible or not.
|
||||
.El
|
||||
|
||||
.Sh SCRIPTS
|
||||
Apart from reading the server and host configuration files,
|
||||
tinc can also run scripts at certain moments.
|
||||
Under Windows (not Cygwin), the scripts should have the extension
|
||||
.Pa .bat .
|
||||
.Bl -tag -width indent
|
||||
|
||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-up
|
||||
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.
|
||||
It should be used to set up the corresponding network interface,
|
||||
but can also be used to start other things.
|
||||
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
|
||||
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
|
||||
This script is started when the tinc daemon with name
|
||||
.Ar HOST
|
||||
becomes reachable.
|
||||
|
||||
.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
|
||||
.Ar HOST
|
||||
becomes unreachable.
|
||||
|
||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /host-up
|
||||
This script is started when any host becomes reachable.
|
||||
|
||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /host-down
|
||||
This script is started when any host becomes unreachable.
|
||||
|
||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /subnet-up
|
||||
This script is started when a Subnet becomes reachable.
|
||||
The Subnet and the node it belongs to are passed in environment variables.
|
||||
|
||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /subnet-down
|
||||
This script is started when a Subnet becomes unreachable.
|
||||
.El
|
||||
|
||||
.Pp
|
||||
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
|
||||
|
@ -725,73 +610,55 @@ files, they have to be put between
|
|||
.Li %
|
||||
signs.
|
||||
.Bl -tag -width indent
|
||||
|
||||
.It Ev NETNAME
|
||||
If a netname was specified, this environment variable contains it.
|
||||
|
||||
.It Ev NAME
|
||||
Contains the name of this tinc daemon.
|
||||
|
||||
.It Ev DEVICE
|
||||
Contains the name of the virtual network device that tinc uses.
|
||||
|
||||
.It Ev INTERFACE
|
||||
Contains the name of the virtual network interface that tinc uses.
|
||||
This should be used for commands like
|
||||
.Pa ifconfig .
|
||||
|
||||
.It Ev NODE
|
||||
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.
|
||||
|
||||
.It Ev REMOTEADDRESS
|
||||
When a host becomes (un)reachable, this is set to its real address.
|
||||
|
||||
.It Ev REMOTEPORT
|
||||
When a host becomes (un)reachable, this is set to the port number it uses for communication with other tinc daemons.
|
||||
|
||||
.It Ev SUBNET
|
||||
When a subnet becomes (un)reachable, this is set to the subnet.
|
||||
|
||||
.It Ev WEIGHT
|
||||
When a subnet becomes (un)reachable, this is set to the subnet weight.
|
||||
.El
|
||||
|
||||
.Pp
|
||||
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 .
|
||||
|
||||
.Sh FILES
|
||||
The most important files are:
|
||||
.Bl -tag -width indent
|
||||
|
||||
.It Pa @sysconfdir@/tinc/
|
||||
The top directory for configuration files.
|
||||
|
||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf
|
||||
The default name of the server configuration file for net
|
||||
.Ar NETNAME .
|
||||
|
||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/
|
||||
Host configuration files are kept in this directory.
|
||||
|
||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-up
|
||||
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 can be used to set up the corresponding network interface.
|
||||
|
||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-down
|
||||
If an executable file with this name exists,
|
||||
it will be executed right before the tinc daemon is going to close
|
||||
its connection to the virtual network device.
|
||||
.El
|
||||
|
||||
.Sh SEE ALSO
|
||||
.Xr tincd 8 ,
|
||||
.Xr tincctl 8 ,
|
||||
.Pa http://www.tinc-vpn.org/ ,
|
||||
.Pa http://www.tldp.org/LDP/nag2/ .
|
||||
|
||||
.Pp
|
||||
The full documentation for
|
||||
.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
|
||||
.Ic info tinc
|
||||
should give you access to the complete manual.
|
||||
|
||||
.Pp
|
||||
.Nm tinc
|
||||
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.
|
||||
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.
|
||||
|
||||
Copyright (C) 1998-2012 Ivo Timmermans, Guus Sliepen
|
||||
|
@ -295,7 +295,8 @@ an error message, and stop.
|
|||
* OpenSSL::
|
||||
* zlib::
|
||||
* lzo::
|
||||
* libevent::
|
||||
* libcurses::
|
||||
* libreadline::
|
||||
|
||||
|
||||
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.
|
||||
|
||||
If this library is not installed, you wil get an error when
|
||||
configuring tinc for build. Support for running tinc without having
|
||||
OpenSSL installed _may_ be added in the future.
|
||||
configuring tinc for build. Support for running tinc with other
|
||||
cryptographic libraries installed _may_ be added in the future.
|
||||
|
||||
You can use your operating system's package manager to install this
|
||||
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
|
||||
provided by the zlib library.
|
||||
|
||||
If this library is not installed, you wil get an error when
|
||||
configuring tinc for build. Support for running tinc without having
|
||||
zlib installed _may_ be added in the future.
|
||||
If this library is not installed, you wil get an error when running
|
||||
the configure script. You can either install the zlib library, or
|
||||
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
|
||||
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).
|
||||
|
||||
|
||||
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
|
||||
---------
|
||||
|
||||
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 tinc for build. Support for running tinc without having lzo
|
||||
installed _may_ be added in the future.
|
||||
If this library is not installed, you wil get an error when running
|
||||
the configure script. You can either install the LZO library, or
|
||||
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
|
||||
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).
|
||||
|
||||
|
||||
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
|
||||
configuring tinc for build.
|
||||
If this library is not installed, you wil get an error when running
|
||||
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
|
||||
if available. Make sure you install the development AND runtime
|
||||
versions of this package.
|
||||
|
||||
If you have to install libevent manually, you can get the source code
|
||||
from `http://libevent.org/'. Instructions on how to configure, build
|
||||
and install this package are included within the package. Please make
|
||||
sure you build development and runtime libraries (which is the default).
|
||||
If you have to install libreadline manually, you can get the source
|
||||
code from `http://www.gnu.org/software/readline/'. Instructions on how
|
||||
to configure, build and install this package are included within the
|
||||
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
|
||||
|
@ -738,6 +773,13 @@ AddressFamily = <ipv4|ipv6|any> (any)
|
|||
system both IPv4 and IPv6 or just IPv6 listening sockets will be
|
||||
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>]
|
||||
If your computer has more than one IPv4 or IPv6 address, tinc will
|
||||
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
|
||||
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)
|
||||
This option selects whether IP addresses (both real and on the VPN)
|
||||
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
|
||||
a relative directory.
|
||||
|
||||
Note that there must be exactly one of PrivateKey or PrivateKeyFile
|
||||
specified in the configuration file.
|
||||
|
||||
ProcessPriority = <low|normal|high>
|
||||
When this option is used the priority of the tincd process will be
|
||||
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
|
||||
(you can use the -c or -n option).
|
||||
|
||||
`dump nodes'
|
||||
Dump a list of all known nodes in the VPN.
|
||||
`dump [reachable] nodes'
|
||||
Dump a list of all known nodes in the VPN. If the reachable
|
||||
keyword is used, only lists reachable nodes.
|
||||
|
||||
`dump edges'
|
||||
Dump a list of all known connections in the VPN.
|
||||
|
@ -2792,14 +2824,16 @@ Concept Index
|
|||
* ANS_KEY: The meta-protocol. (line 64)
|
||||
* authentication: Authentication protocol.
|
||||
(line 6)
|
||||
* AutoConnect: Main configuration variables.
|
||||
(line 12)
|
||||
* binary package: Building and installing tinc.
|
||||
(line 9)
|
||||
* BindToAddress: Main configuration variables.
|
||||
(line 12)
|
||||
(line 19)
|
||||
* BindToInterface: Main configuration variables.
|
||||
(line 23)
|
||||
(line 30)
|
||||
* Broadcast: Main configuration variables.
|
||||
(line 34)
|
||||
(line 41)
|
||||
* Cabal: Security. (line 6)
|
||||
* CHAL_REPLY: Authentication protocol.
|
||||
(line 10)
|
||||
|
@ -2818,29 +2852,29 @@ Concept Index
|
|||
(line 24)
|
||||
* connection: The connection. (line 6)
|
||||
* ConnectTo: Main configuration variables.
|
||||
(line 54)
|
||||
(line 61)
|
||||
* daemon: Running tinc. (line 11)
|
||||
* data-protocol: The meta-connection. (line 18)
|
||||
* debug level: Runtime options. (line 17)
|
||||
* debug levels: Debug levels. (line 6)
|
||||
* DecrementTTL: Main configuration variables.
|
||||
(line 65)
|
||||
(line 72)
|
||||
* DEL_EDGE: The meta-protocol. (line 47)
|
||||
* DEL_SUBNET: The meta-protocol. (line 47)
|
||||
* DEVICE: Scripts. (line 55)
|
||||
* Device: Main configuration variables.
|
||||
(line 74)
|
||||
(line 81)
|
||||
* device files: Device files. (line 6)
|
||||
* DeviceType: Main configuration variables.
|
||||
(line 81)
|
||||
(line 88)
|
||||
* Digest: Host configuration variables.
|
||||
(line 29)
|
||||
* DirectOnly: Main configuration variables.
|
||||
(line 146)
|
||||
* dummy: Main configuration variables.
|
||||
(line 88)
|
||||
* ECDSAPrivateKeyFile: Main configuration variables.
|
||||
(line 153)
|
||||
* dummy: Main configuration variables.
|
||||
(line 95)
|
||||
* ECDSAPrivateKeyFile: Main configuration variables.
|
||||
(line 160)
|
||||
* encapsulating: The UDP tunnel. (line 30)
|
||||
* encryption: Encryption of network packets.
|
||||
(line 6)
|
||||
|
@ -2848,52 +2882,51 @@ Concept Index
|
|||
* example: Example configuration.
|
||||
(line 6)
|
||||
* exec: Main configuration variables.
|
||||
(line 326)
|
||||
(line 322)
|
||||
* ExperimentalProtocol: Main configuration variables.
|
||||
(line 157)
|
||||
(line 164)
|
||||
* Forwarding: Main configuration variables.
|
||||
(line 166)
|
||||
(line 173)
|
||||
* frame type: The UDP tunnel. (line 6)
|
||||
* GraphDumpFile: Main configuration variables.
|
||||
(line 186)
|
||||
* Hostnames: Main configuration variables.
|
||||
(line 194)
|
||||
(line 193)
|
||||
* http: Main configuration variables.
|
||||
(line 323)
|
||||
(line 319)
|
||||
* hub: Main configuration variables.
|
||||
(line 247)
|
||||
(line 246)
|
||||
* ID: Authentication protocol.
|
||||
(line 10)
|
||||
* IndirectData: Host configuration variables.
|
||||
(line 34)
|
||||
* INTERFACE: Scripts. (line 58)
|
||||
* Interface: Main configuration variables.
|
||||
(line 205)
|
||||
(line 204)
|
||||
* IRC: Contact information. (line 9)
|
||||
* KEY_CHANGED: The meta-protocol. (line 64)
|
||||
* KeyExpire: Main configuration variables.
|
||||
(line 252)
|
||||
* libevent: libevent. (line 6)
|
||||
(line 251)
|
||||
* libcurses: libcurses. (line 6)
|
||||
* libraries: Libraries. (line 6)
|
||||
* libreadline: libreadline. (line 6)
|
||||
* license: OpenSSL. (line 36)
|
||||
* LocalDiscovery: Main configuration variables.
|
||||
(line 213)
|
||||
(line 212)
|
||||
* lzo: lzo. (line 6)
|
||||
* MACExpire: Main configuration variables.
|
||||
(line 258)
|
||||
(line 257)
|
||||
* MACLength: Host configuration variables.
|
||||
(line 42)
|
||||
* meta-protocol: The meta-connection. (line 18)
|
||||
* META_KEY: Authentication protocol.
|
||||
(line 10)
|
||||
* Mode: Main configuration variables.
|
||||
(line 224)
|
||||
(line 223)
|
||||
* multicast: Main configuration variables.
|
||||
(line 100)
|
||||
(line 107)
|
||||
* multiple networks: Multiple networks. (line 6)
|
||||
* NAME: Scripts. (line 52)
|
||||
* Name: Main configuration variables.
|
||||
(line 263)
|
||||
(line 262)
|
||||
* netmask: Network interfaces. (line 39)
|
||||
* NETNAME <1>: tincctl environment variables.
|
||||
(line 6)
|
||||
|
@ -2908,9 +2941,9 @@ Concept Index
|
|||
(line 67)
|
||||
* PING: The meta-protocol. (line 89)
|
||||
* PingInterval: Main configuration variables.
|
||||
(line 274)
|
||||
(line 273)
|
||||
* PingTimeout: Main configuration variables.
|
||||
(line 278)
|
||||
(line 277)
|
||||
* platforms: Supported platforms. (line 6)
|
||||
* PMTU: Host configuration variables.
|
||||
(line 47)
|
||||
|
@ -2921,32 +2954,32 @@ Concept Index
|
|||
(line 55)
|
||||
* port numbers: Other files. (line 17)
|
||||
* PriorityInheritance: Main configuration variables.
|
||||
(line 284)
|
||||
(line 283)
|
||||
* private: Virtual Private Networks.
|
||||
(line 10)
|
||||
* PrivateKey: Main configuration variables.
|
||||
(line 289)
|
||||
(line 288)
|
||||
* PrivateKeyFile: Main configuration variables.
|
||||
(line 295)
|
||||
(line 294)
|
||||
* ProcessPriority: Main configuration variables.
|
||||
(line 303)
|
||||
(line 299)
|
||||
* Proxy: Main configuration variables.
|
||||
(line 308)
|
||||
(line 304)
|
||||
* PublicKey: Host configuration variables.
|
||||
(line 59)
|
||||
* PublicKeyFile: Host configuration variables.
|
||||
(line 62)
|
||||
* raw_socket: Main configuration variables.
|
||||
(line 93)
|
||||
(line 100)
|
||||
* release: Supported platforms. (line 14)
|
||||
* REMOTEADDRESS: Scripts. (line 67)
|
||||
* REMOTEPORT: Scripts. (line 70)
|
||||
* ReplayWindow: Main configuration variables.
|
||||
(line 331)
|
||||
(line 327)
|
||||
* REQ_KEY: The meta-protocol. (line 64)
|
||||
* requirements: Libraries. (line 6)
|
||||
* router: Main configuration variables.
|
||||
(line 227)
|
||||
(line 226)
|
||||
* runtime options: Runtime options. (line 9)
|
||||
* scalability: tinc. (line 19)
|
||||
* scripts: Scripts. (line 6)
|
||||
|
@ -2954,17 +2987,17 @@ Concept Index
|
|||
(line 18)
|
||||
* signals: Signals. (line 6)
|
||||
* socks4: Main configuration variables.
|
||||
(line 312)
|
||||
(line 308)
|
||||
* socks5: Main configuration variables.
|
||||
(line 317)
|
||||
(line 313)
|
||||
* StrictSubnets: Main configuration variables.
|
||||
(line 342)
|
||||
(line 338)
|
||||
* SUBNET: Scripts. (line 74)
|
||||
* Subnet: Host configuration variables.
|
||||
(line 74)
|
||||
* SVPN: Security. (line 11)
|
||||
* switch: Main configuration variables.
|
||||
(line 236)
|
||||
(line 235)
|
||||
* TCP: The meta-connection. (line 10)
|
||||
* TCPonly: Host configuration variables.
|
||||
(line 103)
|
||||
|
@ -2976,24 +3009,24 @@ Concept Index
|
|||
* tincd: tinc. (line 14)
|
||||
* traditional VPNs: tinc. (line 19)
|
||||
* tunifhead: Main configuration variables.
|
||||
(line 135)
|
||||
(line 142)
|
||||
* TunnelServer: Main configuration variables.
|
||||
(line 347)
|
||||
(line 343)
|
||||
* tunnohead: Main configuration variables.
|
||||
(line 129)
|
||||
(line 136)
|
||||
* UDP <1>: Encryption of network packets.
|
||||
(line 12)
|
||||
* UDP: The UDP tunnel. (line 30)
|
||||
* UDPRcvBuf: Main configuration variables.
|
||||
(line 354)
|
||||
(line 350)
|
||||
* UDPSndBuf: Main configuration variables.
|
||||
(line 359)
|
||||
(line 355)
|
||||
* UML: Main configuration variables.
|
||||
(line 111)
|
||||
(line 118)
|
||||
* Universal tun/tap: Configuration of Linux kernels.
|
||||
(line 6)
|
||||
* VDE: Main configuration variables.
|
||||
(line 116)
|
||||
(line 123)
|
||||
* virtual: Virtual Private Networks.
|
||||
(line 18)
|
||||
* 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 Windows10241
|
||||
Node: Libraries10755
|
||||
Node: OpenSSL11156
|
||||
Node: zlib13432
|
||||
Node: lzo14261
|
||||
Node: libevent15065
|
||||
Node: Installation15760
|
||||
Node: Building and installing tinc16776
|
||||
Node: Darwin (MacOS/X) build environment17435
|
||||
Node: Cygwin (Windows) build environment18002
|
||||
Node: MinGW (Windows) build environment18590
|
||||
Node: System files19114
|
||||
Node: Device files19379
|
||||
Node: Other files19795
|
||||
Node: Configuration20408
|
||||
Node: Configuration introduction20695
|
||||
Node: Multiple networks22242
|
||||
Node: How connections work23622
|
||||
Node: Configuration files26195
|
||||
Node: Main configuration variables27728
|
||||
Node: Host configuration variables44334
|
||||
Node: Scripts49564
|
||||
Node: How to configure52243
|
||||
Node: Network interfaces56861
|
||||
Node: Example configuration59262
|
||||
Node: Running tinc64414
|
||||
Node: Runtime options65007
|
||||
Node: Signals67711
|
||||
Node: Debug levels68561
|
||||
Node: Solving problems69497
|
||||
Node: Error messages70927
|
||||
Node: Sending bug reports75249
|
||||
Node: Controlling tinc76201
|
||||
Node: tincctl runtime options76598
|
||||
Node: tincctl environment variables77297
|
||||
Node: tincctl commands77641
|
||||
Node: tincctl examples81866
|
||||
Node: tincctl top82471
|
||||
Node: Technical information84069
|
||||
Node: The connection84304
|
||||
Node: The UDP tunnel84616
|
||||
Node: The meta-connection87677
|
||||
Node: The meta-protocol89146
|
||||
Node: Security94155
|
||||
Node: Authentication protocol95285
|
||||
Node: Encryption of network packets100289
|
||||
Node: Security issues101662
|
||||
Node: Platform specific information103279
|
||||
Node: Interface configuration103507
|
||||
Node: Routes105960
|
||||
Node: About us107876
|
||||
Node: Contact information108051
|
||||
Node: Authors108455
|
||||
Node: Concept Index108860
|
||||
Node: OpenSSL11173
|
||||
Node: zlib13461
|
||||
Node: lzo14487
|
||||
Node: libcurses15485
|
||||
Node: libreadline16405
|
||||
Node: Installation17353
|
||||
Node: Building and installing tinc18369
|
||||
Node: Darwin (MacOS/X) build environment19028
|
||||
Node: Cygwin (Windows) build environment19595
|
||||
Node: MinGW (Windows) build environment20183
|
||||
Node: System files20707
|
||||
Node: Device files20972
|
||||
Node: Other files21388
|
||||
Node: Configuration22001
|
||||
Node: Configuration introduction22288
|
||||
Node: Multiple networks23835
|
||||
Node: How connections work25215
|
||||
Node: Configuration files27788
|
||||
Node: Main configuration variables29321
|
||||
Node: Host configuration variables45731
|
||||
Node: Scripts50961
|
||||
Node: How to configure53640
|
||||
Node: Network interfaces58258
|
||||
Node: Example configuration60659
|
||||
Node: Running tinc65811
|
||||
Node: Runtime options66404
|
||||
Node: Signals69108
|
||||
Node: Debug levels69958
|
||||
Node: Solving problems70894
|
||||
Node: Error messages72324
|
||||
Node: Sending bug reports76646
|
||||
Node: Controlling tinc77598
|
||||
Node: tincctl runtime options77995
|
||||
Node: tincctl environment variables78694
|
||||
Node: tincctl commands79038
|
||||
Node: tincctl examples83343
|
||||
Node: tincctl top83948
|
||||
Node: Technical information85546
|
||||
Node: The connection85781
|
||||
Node: The UDP tunnel86093
|
||||
Node: The meta-connection89154
|
||||
Node: The meta-protocol90623
|
||||
Node: Security95632
|
||||
Node: Authentication protocol96762
|
||||
Node: Encryption of network packets101766
|
||||
Node: Security issues103139
|
||||
Node: Platform specific information104756
|
||||
Node: Interface configuration104984
|
||||
Node: Routes107437
|
||||
Node: About us109353
|
||||
Node: Contact information109528
|
||||
Node: Authors109932
|
||||
Node: Concept Index110337
|
||||
|
||||
End Tag Table
|
||||
|
|
|
@ -339,7 +339,8 @@ having them installed, configure will give you an error message, and stop.
|
|||
* OpenSSL::
|
||||
* zlib::
|
||||
* lzo::
|
||||
* libevent::
|
||||
* libcurses::
|
||||
* libreadline::
|
||||
@end menu
|
||||
|
||||
|
||||
|
@ -352,7 +353,7 @@ For all cryptography-related functions, tinc uses the functions provided
|
|||
by the OpenSSL library.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
by the zlib library.
|
||||
|
||||
If this library is not installed, you wil get an error when configuring
|
||||
tinc for build. Support for running tinc without having zlib
|
||||
installed @emph{may} be added in the future.
|
||||
If this library is not installed, you wil get an error when running the
|
||||
configure script. You can either install the zlib library, or 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 if
|
||||
available. Make sure you install the development AND runtime versions
|
||||
|
@ -435,11 +438,13 @@ default).
|
|||
@subsection 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
|
||||
tinc for build. Support for running tinc without having lzo
|
||||
installed @emph{may} be added in the future.
|
||||
If this library is not installed, you wil get an error when running the
|
||||
configure script. You can either install the LZO library, or 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 if
|
||||
available. Make sure you install the development AND runtime versions
|
||||
|
@ -453,24 +458,48 @@ default).
|
|||
|
||||
|
||||
@c ==================================================================
|
||||
@node libevent
|
||||
@subsection libevent
|
||||
@node libcurses
|
||||
@subsection libcurses
|
||||
|
||||
@cindex libevent
|
||||
For the main event loop, tinc uses the libevent library.
|
||||
@cindex libcurses
|
||||
For the "tincctl top" command, tinc requires a curses library.
|
||||
|
||||
If this library is not installed, you wil get an error when configuring
|
||||
tinc for build.
|
||||
If this library is not installed, you wil get an error when running 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" (@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
|
||||
available. Make sure you install the development AND runtime versions
|
||||
of this package.
|
||||
|
||||
If you have to install libevent manually, you can get the source code
|
||||
from @url{http://libevent.org/}. Instructions on how to configure,
|
||||
build and install this package are included within the package. Please
|
||||
make sure you build development and runtime libraries (which is the
|
||||
default).
|
||||
If you have to install libreadline manually, you can get the source code from
|
||||
@url{http://www.gnu.org/software/readline/}. Instructions on how to configure,
|
||||
build and install this package are included within the package. Please make
|
||||
sure you build development and runtime libraries (which is the default).
|
||||
|
||||
|
||||
@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
|
||||
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
|
||||
@item BindToAddress = <@var{address}> [<@var{port}>]
|
||||
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.
|
||||
@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
|
||||
@item Hostnames = <yes|no> (no)
|
||||
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
|
||||
relative directory.
|
||||
|
||||
Note that there must be exactly one of PrivateKey
|
||||
or PrivateKeyFile
|
||||
specified in the configuration file.
|
||||
|
||||
@cindex ProcessPriority
|
||||
@item ProcessPriority = <low|normal|high>
|
||||
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
|
||||
option).
|
||||
|
||||
@item dump nodes
|
||||
@item dump [reachable] nodes
|
||||
Dump a list of all known nodes in the VPN.
|
||||
If the reachable keyword is used, only lists reachable nodes.
|
||||
|
||||
@item dump edges
|
||||
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.
|
||||
.El
|
||||
.Sh COMMANDS
|
||||
.zZ
|
||||
.Bl -tag -width indent
|
||||
.It init Op Ar name
|
||||
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.
|
||||
When saving keys to existing files, tinc will not delete the old keys;
|
||||
you have to remove them manually.
|
||||
|
||||
.It dump nodes
|
||||
.It dump [reachable] nodes
|
||||
Dump a list of all known nodes in the VPN.
|
||||
If the keyword reachable is used, only lists reachable nodes.
|
||||
.It dump edges
|
||||
Dump a list of all known connections in the VPN.
|
||||
.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 ConnectTo bar
|
||||
tincctl -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@example.com
|
||||
.Ed
|
||||
.Sh TOP
|
||||
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,
|
||||
|
|
|
@ -56,10 +56,9 @@ DIST_COMMON = $(dist_bin_SCRIPTS) $(srcdir)/Makefile.am \
|
|||
$(srcdir)/Makefile.in
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
|
||||
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libevent.m4 \
|
||||
$(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \
|
||||
$(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \
|
||||
$(top_srcdir)/configure.in
|
||||
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/lzo.m4 \
|
||||
$(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \
|
||||
$(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.in
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
mkinstalldirs = $(install_sh) -d
|
||||
|
|
4
have.h
4
have.h
|
@ -196,10 +196,6 @@
|
|||
#include <netinet/if_ether.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_EVENT_H
|
||||
#include <event.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MINGW
|
||||
#define SLASH "\\"
|
||||
#else
|
||||
|
|
|
@ -54,10 +54,9 @@ subdir = m4
|
|||
DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
|
||||
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libevent.m4 \
|
||||
$(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \
|
||||
$(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \
|
||||
$(top_srcdir)/configure.in
|
||||
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/lzo.m4 \
|
||||
$(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \
|
||||
$(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.in
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
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 \
|
||||
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 \
|
||||
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
|
||||
|
||||
if UML
|
||||
|
@ -46,7 +46,7 @@ INCLUDES = @INCLUDES@ -I$(top_builddir)
|
|||
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 \
|
||||
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 = \
|
||||
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
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
|
||||
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libevent.m4 \
|
||||
$(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \
|
||||
$(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \
|
||||
$(top_srcdir)/configure.in
|
||||
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/lzo.m4 \
|
||||
$(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \
|
||||
$(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.in
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
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 \
|
||||
protocol_edge.c protocol_misc.c protocol_key.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 \
|
||||
uml_device.c vde_device.c bsd/tunemu.c
|
||||
event.c tincd.c dummy_device.c raw_socket_device.c \
|
||||
multicast_device.c uml_device.c vde_device.c bsd/tunemu.c
|
||||
@UML_TRUE@am__objects_1 = uml_device.$(OBJEXT)
|
||||
@VDE_TRUE@am__objects_2 = vde_device.$(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_key.$(OBJEXT) protocol_subnet.$(OBJEXT) \
|
||||
route.$(OBJEXT) sptps.$(OBJEXT) subnet.$(OBJEXT) \
|
||||
subnet_parse.$(OBJEXT) tincd.$(OBJEXT) dummy_device.$(OBJEXT) \
|
||||
raw_socket_device.$(OBJEXT) multicast_device.$(OBJEXT) \
|
||||
$(am__objects_1) $(am__objects_2) $(am__objects_3)
|
||||
subnet_parse.$(OBJEXT) event.$(OBJEXT) tincd.$(OBJEXT) \
|
||||
dummy_device.$(OBJEXT) raw_socket_device.$(OBJEXT) \
|
||||
multicast_device.$(OBJEXT) $(am__objects_1) $(am__objects_2) \
|
||||
$(am__objects_3)
|
||||
nodist_tincd_OBJECTS = device.$(OBJEXT) cipher.$(OBJEXT) \
|
||||
crypto.$(OBJEXT) ecdh.$(OBJEXT) ecdsa.$(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 \
|
||||
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 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) \
|
||||
$(am__append_2) $(am__append_3)
|
||||
nodist_tincd_SOURCES = \
|
||||
|
@ -273,7 +273,7 @@ DEFAULT_INCLUDES =
|
|||
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 \
|
||||
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 = \
|
||||
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)/ecdsagen.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-getnameinfo.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->outbuf);
|
||||
|
||||
if(event_initialized(&c->inevent))
|
||||
event_del(&c->inevent);
|
||||
|
||||
if(event_initialized(&c->outevent))
|
||||
event_del(&c->outevent);
|
||||
io_del(&c->io);
|
||||
|
||||
if(c->socket > 0)
|
||||
closesocket(c->socket);
|
||||
|
|
|
@ -90,8 +90,7 @@ typedef struct connection_t {
|
|||
|
||||
struct buffer_t inbuf;
|
||||
struct buffer_t outbuf;
|
||||
struct event inevent; /* input event on this metadata connection */
|
||||
struct event outevent; /* output event on this metadata connection */
|
||||
io_t io; /* input/output event on this metadata connection */
|
||||
int tcplen; /* length of incoming TCPpacket */
|
||||
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) {
|
||||
case REQ_STOP:
|
||||
event_loopexit(NULL);
|
||||
event_exit();
|
||||
return control_ok(c, REQ_STOP);
|
||||
|
||||
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.
|
||||
|
||||
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);
|
||||
} else {
|
||||
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);
|
||||
#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__ */
|
||||
|
|
|
@ -41,6 +41,10 @@
|
|||
#define ETH_P_IPV6 0x86DD
|
||||
#endif
|
||||
|
||||
#ifndef ETH_P_8021Q
|
||||
#define ETH_P_8021Q 0x8100
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_ETHER_HEADER
|
||||
struct ether_header {
|
||||
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->mtuprobes = 0;
|
||||
|
||||
if(timeout_initialized(&n->mtuevent))
|
||||
event_del(&n->mtuevent);
|
||||
timeout_del(&n->mtutimeout);
|
||||
|
||||
char *name;
|
||||
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->n = n;
|
||||
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);
|
||||
return hash;
|
||||
}
|
||||
|
@ -100,6 +100,8 @@ void hash_clear(hash_t *hash) {
|
|||
void hash_resize(hash_t *hash, size_t n) {
|
||||
hash->keys = xrealloc(hash->keys, n * hash->size);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,6 @@ bool logcontrol = false;
|
|||
|
||||
static void real_logger(int level, int priority, const char *message) {
|
||||
char timestr[32] = "";
|
||||
time_t now;
|
||||
static bool suppress = false;
|
||||
|
||||
// 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);
|
||||
break;
|
||||
case LOGMODE_FILE:
|
||||
now = time(NULL);
|
||||
strftime(timestr, sizeof timestr, "%Y-%m-%d %H:%M:%S", localtime(&now));
|
||||
if(!now.tv_sec)
|
||||
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);
|
||||
fflush(logfile);
|
||||
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);
|
||||
event_add(&c->outevent, NULL);
|
||||
io_set(&c->io, IO_READ | IO_WRITE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -65,12 +65,11 @@ bool send_meta(connection_t *c, const char *buffer, int length) {
|
|||
c->name, c->hostname);
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
buffer_add(&c->outbuf, buffer, length);
|
||||
}
|
||||
|
||||
event_add(&c->outevent, NULL);
|
||||
io_set(&c->io, IO_READ | IO_WRITE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
175
src/net.c
175
src/net.c
|
@ -74,7 +74,7 @@ void purge(void) {
|
|||
if(e->to == n)
|
||||
return;
|
||||
|
||||
if(!strictsubnets || !n->subnet_tree->head)
|
||||
if(!autoconnect && (!strictsubnets || !n->subnet_tree->head))
|
||||
/* in strictsubnets mode do not delete nodes with subnets */
|
||||
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
|
||||
and close the connection.
|
||||
*/
|
||||
static void timeout_handler(int fd, short events, void *event) {
|
||||
time_t now = time(NULL);
|
||||
|
||||
static void timeout_handler(void *data) {
|
||||
for list_each(connection_t, c, connection_list) {
|
||||
if(c->status.control)
|
||||
continue;
|
||||
|
||||
if(c->last_ping_time + pingtimeout <= now) {
|
||||
if(c->last_ping_time + pingtimeout <= now.tv_sec) {
|
||||
if(c->status.active) {
|
||||
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);
|
||||
} else if(c->last_ping_time + pinginterval <= now) {
|
||||
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.tv_sec) {
|
||||
send_ping(c);
|
||||
continue;
|
||||
} 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) {
|
||||
logger(DEBUG_ALWAYS, LOG_WARNING, "Possible node with same Name as us! Sleeping %d seconds.", sleeptime);
|
||||
usleep(sleeptime * 1000000LL);
|
||||
|
@ -179,11 +186,100 @@ static void timeout_handler(int fd, short events, void *event) {
|
|||
contradicting_add_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) {
|
||||
connection_t *c = data;
|
||||
void handle_meta_connection_data(connection_t *c) {
|
||||
int 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) {
|
||||
logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(signal));
|
||||
event_loopexit(NULL);
|
||||
static void sigterm_handler(void *data) {
|
||||
logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum));
|
||||
event_exit();
|
||||
}
|
||||
|
||||
static void sighup_handler(int signal, short events, void *data) {
|
||||
logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(signal));
|
||||
static void sighup_handler(void *data) {
|
||||
logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum));
|
||||
reopenlogger();
|
||||
reload_configuration();
|
||||
}
|
||||
|
||||
static void sigalrm_handler(int signal, short events, void *data) {
|
||||
logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(signal));
|
||||
static void sigalrm_handler(void *data) {
|
||||
logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum));
|
||||
retry();
|
||||
}
|
||||
|
||||
|
@ -233,7 +329,7 @@ int reload_configuration(void) {
|
|||
|
||||
if(!read_server_config()) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Unable to reread configuration file, exitting.");
|
||||
event_loopexit(NULL);
|
||||
event_exit();
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
|
@ -332,8 +428,7 @@ int reload_configuration(void) {
|
|||
void retry(void) {
|
||||
for list_each(connection_t, c, connection_list) {
|
||||
if(c->outgoing && !c->node) {
|
||||
if(timeout_initialized(&c->outgoing->ev))
|
||||
event_del(&c->outgoing->ev);
|
||||
timeout_del(&c->outgoing->ev);
|
||||
if(c->status.connecting)
|
||||
close(c->socket);
|
||||
c->outgoing->timeout = 0;
|
||||
|
@ -346,40 +441,38 @@ void retry(void) {
|
|||
this is where it all happens...
|
||||
*/
|
||||
int main_loop(void) {
|
||||
struct event timeout_event;
|
||||
timeout_t pingtimer = {{0}};
|
||||
timeout_t periodictimer = {{0}};
|
||||
|
||||
timeout_set(&timeout_event, timeout_handler, &timeout_event);
|
||||
event_add(&timeout_event, &(struct timeval){pingtimeout, 0});
|
||||
timeout_add(&pingtimer, timeout_handler, &pingtimer, &(struct timeval){pingtimeout, rand() % 100000});
|
||||
timeout_add(&periodictimer, periodic_handler, &periodictimer, &(struct timeval){pingtimeout, rand() % 100000});
|
||||
|
||||
#ifndef HAVE_MINGW
|
||||
struct event sighup_event;
|
||||
struct event sigterm_event;
|
||||
struct event sigquit_event;
|
||||
struct event sigalrm_event;
|
||||
signal_t sighup = {0};
|
||||
signal_t sigterm = {0};
|
||||
signal_t sigquit = {0};
|
||||
signal_t sigalrm = {0};
|
||||
|
||||
signal_set(&sighup_event, SIGHUP, sighup_handler, NULL);
|
||||
signal_add(&sighup_event, NULL);
|
||||
signal_set(&sigterm_event, SIGTERM, sigterm_handler, NULL);
|
||||
signal_add(&sigterm_event, NULL);
|
||||
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);
|
||||
signal_add(&sighup, sighup_handler, &sighup, SIGHUP);
|
||||
signal_add(&sigterm, sigterm_handler, &sigterm, SIGTERM);
|
||||
signal_add(&sigquit, sigterm_handler, &sigquit, SIGQUIT);
|
||||
signal_add(&sigalrm, sigalrm_handler, &sigalrm, SIGALRM);
|
||||
#endif
|
||||
|
||||
if(event_loop(0) < 0) {
|
||||
if(!event_loop()) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error while waiting for input: %s", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef HAVE_MINGW
|
||||
signal_del(&sighup_event);
|
||||
signal_del(&sigterm_event);
|
||||
signal_del(&sigquit_event);
|
||||
signal_del(&sigalrm_event);
|
||||
signal_del(&sighup);
|
||||
signal_del(&sigalrm);
|
||||
signal_del(&sigquit);
|
||||
signal_del(&sigterm);
|
||||
#endif
|
||||
|
||||
event_del(&timeout_event);
|
||||
timeout_del(&periodictimer);
|
||||
timeout_del(&pingtimer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
19
src/net.h
19
src/net.h
|
@ -24,6 +24,7 @@
|
|||
#include "ipv6.h"
|
||||
#include "cipher.h"
|
||||
#include "digest.h"
|
||||
#include "event.h"
|
||||
|
||||
#ifdef ENABLE_JUMBOGRAMS
|
||||
#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;
|
||||
|
||||
typedef struct listen_socket_t {
|
||||
struct event ev_tcp;
|
||||
struct event ev_udp;
|
||||
int tcp;
|
||||
int udp;
|
||||
io_t tcp;
|
||||
io_t udp;
|
||||
sockaddr_t sa;
|
||||
} listen_socket_t;
|
||||
|
||||
|
@ -116,7 +115,7 @@ typedef struct outgoing_t {
|
|||
struct config_t *cfg;
|
||||
struct addrinfo *ai;
|
||||
struct addrinfo *aip;
|
||||
struct event ev;
|
||||
timeout_t ev;
|
||||
} outgoing_t;
|
||||
|
||||
extern list_t *outgoing_list;
|
||||
|
@ -134,6 +133,7 @@ extern int udp_rcvbuf;
|
|||
extern int udp_sndbuf;
|
||||
extern bool do_prune;
|
||||
extern char *myport;
|
||||
extern int autoconnect;
|
||||
extern int contradicting_add_edge;
|
||||
extern int contradicting_del_edge;
|
||||
extern time_t last_config_check;
|
||||
|
@ -160,10 +160,10 @@ extern char *scriptextension;
|
|||
#include "node.h"
|
||||
|
||||
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 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_vpn_in_socket(const sockaddr_t *);
|
||||
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_rsa_public_key(struct connection_t *);
|
||||
extern void send_mtu_probe(struct node_t *);
|
||||
extern void handle_device_data(int, short, void *);
|
||||
extern void handle_meta_connection_data(int, short, void *);
|
||||
extern void handle_device_data(void *, int);
|
||||
extern void handle_meta_connection_data(struct connection_t *);
|
||||
extern void regenerate_key(void);
|
||||
extern void purge(void);
|
||||
extern void retry(void);
|
||||
extern int reload_configuration(void);
|
||||
extern void load_all_subnets(void);
|
||||
extern void load_all_nodes(void);
|
||||
|
||||
#ifndef HAVE_MINGW
|
||||
#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.
|
||||
*/
|
||||
|
||||
static void send_mtu_probe_handler(int fd, short events, void *data) {
|
||||
static void send_mtu_probe_handler(void *data) {
|
||||
node_t *n = data;
|
||||
int timeout = 1;
|
||||
|
||||
|
@ -151,23 +151,37 @@ static void send_mtu_probe_handler(int fd, short events, void *data) {
|
|||
}
|
||||
|
||||
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) {
|
||||
if(!timeout_initialized(&n->mtuevent))
|
||||
timeout_set(&n->mtuevent, send_mtu_probe_handler, n);
|
||||
send_mtu_probe_handler(0, 0, n);
|
||||
timeout_add(&n->mtutimeout, send_mtu_probe_handler, n, &(struct timeval){1, 0});
|
||||
send_mtu_probe_handler(n);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if(!packet->data[0]) {
|
||||
/* It's a probe request, send back a reply */
|
||||
|
||||
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;
|
||||
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->minmtu)
|
||||
|
@ -176,6 +190,8 @@ static void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) {
|
|||
n->mtuprobes = 1;
|
||||
}
|
||||
|
||||
/* If applicable, raise the minimum supported MTU */
|
||||
|
||||
if(len > n->maxmtu)
|
||||
len = n->maxmtu;
|
||||
if(n->minmtu < len)
|
||||
|
@ -438,6 +454,84 @@ static void send_sptps_packet(node_t *n, vpn_packet_t *origpkt) {
|
|||
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) {
|
||||
vpn_packet_t 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 */
|
||||
|
||||
if(!n->status.validkey) {
|
||||
time_t now = time(NULL);
|
||||
|
||||
logger(DEBUG_TRAFFIC, LOG_INFO,
|
||||
"No valid key known yet for %s (%s), forwarding via TCP",
|
||||
n->name, n->hostname);
|
||||
|
||||
if(n->last_req_key + 10 <= now) {
|
||||
if(n->last_req_key + 10 <= now.tv_sec) {
|
||||
send_req_key(n);
|
||||
n->last_req_key = now;
|
||||
n->last_req_key = now.tv_sec;
|
||||
}
|
||||
|
||||
send_tcppacket(n->nexthop->connection, origpkt);
|
||||
|
@ -534,88 +626,27 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
|
|||
|
||||
/* Send the packet */
|
||||
|
||||
sockaddr_t *sa;
|
||||
const sockaddr_t *sa;
|
||||
int sock;
|
||||
|
||||
/* Overloaded use of priority field: -1 means local broadcast */
|
||||
|
||||
if(origpriority == -1 && n->prevedge) {
|
||||
sockaddr_t broadcast;
|
||||
broadcast.in.sin_family = AF_INET;
|
||||
broadcast.in.sin_addr.s_addr = -1;
|
||||
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(origpriority == -1 && n->prevedge)
|
||||
choose_broadcast_address(n, &sa, &sock);
|
||||
else
|
||||
choose_udp_address(n, &sa, &sock);
|
||||
|
||||
#if defined(SOL_IP) && defined(IP_TOS)
|
||||
if(priorityinheritance && origpriority != priority
|
||||
&& listen_socket[n->sock].sa.sa.sa_family == AF_INET) {
|
||||
priority = origpriority;
|
||||
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));
|
||||
}
|
||||
#endif
|
||||
|
||||
socklen_t sl = SALEN(n->address.sa);
|
||||
|
||||
if(sendto(listen_socket[sock].udp, (char *) &inpkt->seqno, inpkt->len, 0, &sa->sa, sl) < 0 && !sockwouldblock(sockerrno)) {
|
||||
if(sendto(listen_socket[sock].udp.fd, (char *) &inpkt->seqno, inpkt->len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) {
|
||||
if(sockmsgsize(sockerrno)) {
|
||||
if(n->maxmtu >= origlen)
|
||||
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 */
|
||||
|
||||
struct sockaddr *sa;
|
||||
socklen_t sl;
|
||||
const sockaddr_t *sa;
|
||||
int sock;
|
||||
|
||||
sa = &(to->address.sa);
|
||||
sl = SALEN(to->address.sa);
|
||||
sock = to->sock;
|
||||
choose_udp_address(to, &sa, &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(to->maxmtu >= len)
|
||||
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;
|
||||
if(type & PKT_COMPRESSED) {
|
||||
len = uncompress_packet(inpkt.data + offset, (const uint8_t *)data, len, from->incompression);
|
||||
if(len < 0) {
|
||||
length_t ulen = uncompress_packet(inpkt.data + offset, (const uint8_t *)data, len, from->incompression);
|
||||
if(ulen < 0) {
|
||||
return false;
|
||||
} else {
|
||||
inpkt.len = len + offset;
|
||||
inpkt.len = ulen + offset;
|
||||
}
|
||||
if(inpkt.len > MAXSIZE)
|
||||
abort();
|
||||
|
@ -838,14 +866,13 @@ static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) {
|
|||
node_t *n = NULL;
|
||||
bool hard = false;
|
||||
static time_t last_hard_try = 0;
|
||||
time_t now = time(NULL);
|
||||
|
||||
for splay_each(edge_t, e, edge_weight_tree) {
|
||||
if(!e->to->status.reachable || e->to == myself)
|
||||
continue;
|
||||
|
||||
if(sockaddrcmp_noport(from, &e->address)) {
|
||||
if(last_hard_try == now)
|
||||
if(last_hard_try == now.tv_sec)
|
||||
continue;
|
||||
hard = true;
|
||||
}
|
||||
|
@ -858,13 +885,14 @@ static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) {
|
|||
}
|
||||
|
||||
if(hard)
|
||||
last_hard_try = now;
|
||||
last_hard_try = now.tv_sec;
|
||||
|
||||
last_hard_try = now;
|
||||
last_hard_try = now.tv_sec;
|
||||
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;
|
||||
char *hostname;
|
||||
sockaddr_t from = {{0}};
|
||||
|
@ -872,7 +900,7 @@ void handle_incoming_vpn_data(int sock, short events, void *data) {
|
|||
node_t *n;
|
||||
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(!sockwouldblock(sockerrno))
|
||||
|
@ -900,12 +928,12 @@ void handle_incoming_vpn_data(int sock, short events, void *data) {
|
|||
return;
|
||||
}
|
||||
|
||||
n->sock = (intptr_t)data;
|
||||
n->sock = ls - listen_socket;
|
||||
|
||||
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;
|
||||
|
||||
packet.priority = 0;
|
||||
|
|
127
src/net_setup.c
127
src/net_setup.c
|
@ -42,7 +42,7 @@
|
|||
#include "xalloc.h"
|
||||
|
||||
char *myport;
|
||||
static struct event device_ev;
|
||||
static io_t device_io;
|
||||
devops_t devops;
|
||||
|
||||
char *proxyhost;
|
||||
|
@ -50,6 +50,7 @@ char *proxyport;
|
|||
char *proxyuser;
|
||||
char *proxypass;
|
||||
proxytype_t proxytype;
|
||||
int autoconnect;
|
||||
|
||||
char *scriptinterpreter;
|
||||
char *scriptextension;
|
||||
|
@ -269,22 +270,16 @@ static bool read_rsa_private_key(void) {
|
|||
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();
|
||||
timeout_set(data, &(struct timeval){keylifetime, rand() % 100000});
|
||||
}
|
||||
|
||||
void regenerate_key(void) {
|
||||
if(timeout_initialized(&keyexpire_event)) {
|
||||
logger(DEBUG_STATUS, LOG_INFO, "Expiring symmetric keys");
|
||||
event_del(&keyexpire_event);
|
||||
send_key_changed();
|
||||
} else {
|
||||
timeout_set(&keyexpire_event, keyexpire_handler, NULL);
|
||||
}
|
||||
|
||||
event_add(&keyexpire_event, &(struct timeval){keylifetime, 0});
|
||||
logger(DEBUG_STATUS, LOG_INFO, "Expiring symmetric keys");
|
||||
send_key_changed();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -347,6 +342,36 @@ void load_all_subnets(void) {
|
|||
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 *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);
|
||||
return false;
|
||||
}
|
||||
envname = alloca(32);
|
||||
char envname[32];
|
||||
if(gethostname(envname, 32)) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Could not get hostname: %s\n", strerror(errno));
|
||||
return false;
|
||||
|
@ -570,6 +595,8 @@ bool setup_myself_reloadable(void) {
|
|||
if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime))
|
||||
keylifetime = 3600;
|
||||
|
||||
get_config_int(lookup_config(config_tree, "AutoConnect"), &autoconnect);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -683,7 +710,8 @@ static bool setup_myself(void) {
|
|||
|
||||
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... */
|
||||
|
||||
|
@ -730,6 +758,8 @@ static bool setup_myself(void) {
|
|||
|
||||
if(strictsubnets)
|
||||
load_all_subnets();
|
||||
else if(autoconnect)
|
||||
load_all_nodes();
|
||||
|
||||
/* Open device */
|
||||
|
||||
|
@ -755,15 +785,8 @@ static bool setup_myself(void) {
|
|||
if(!devops.setup())
|
||||
return false;
|
||||
|
||||
if(device_fd >= 0) {
|
||||
event_set(&device_ev, device_fd, EV_READ|EV_PERSIST, handle_device_data, NULL);
|
||||
|
||||
if (event_add(&device_ev, NULL) < 0) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "event_add failed: %s", strerror(errno));
|
||||
devops.close();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(device_fd >= 0)
|
||||
io_add(&device_io, handle_device_data, NULL, device_fd, IO_READ);
|
||||
|
||||
/* Run tinc-up script to further initialize the tap interface */
|
||||
char *envp[5];
|
||||
|
@ -805,27 +828,16 @@ static bool setup_myself(void) {
|
|||
return false;
|
||||
}
|
||||
|
||||
listen_socket[i].tcp = i + 3;
|
||||
|
||||
#ifdef FD_CLOEXEC
|
||||
fcntl(i + 3, F_SETFD, FD_CLOEXEC);
|
||||
#endif
|
||||
|
||||
listen_socket[i].udp = setup_vpn_in_socket(&sa);
|
||||
if(listen_socket[i].udp < 0)
|
||||
int udp_fd = setup_vpn_in_socket(&sa);
|
||||
if(udp_fd < 0)
|
||||
return false;
|
||||
|
||||
event_set(&listen_socket[i].ev_tcp, listen_socket[i].tcp, EV_READ|EV_PERSIST, handle_new_meta_connection, NULL);
|
||||
if(event_add(&listen_socket[i].ev_tcp, NULL) < 0) {
|
||||
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();
|
||||
}
|
||||
io_add(&listen_socket[i].tcp, (io_cb_t)handle_new_meta_connection, &listen_socket[i], i + 3, IO_READ);
|
||||
io_add(&listen_socket[i].udp, (io_cb_t)handle_incoming_vpn_data, &listen_socket[i], udp_fd, IO_READ);
|
||||
|
||||
if(debug_level >= DEBUG_CONNECTIONS) {
|
||||
hostname = sockaddr2hostname(&sa);
|
||||
|
@ -878,37 +890,20 @@ static bool setup_myself(void) {
|
|||
return false;
|
||||
}
|
||||
|
||||
listen_socket[listen_sockets].tcp =
|
||||
setup_listen_socket((sockaddr_t *) aip->ai_addr);
|
||||
int tcp_fd = setup_listen_socket((sockaddr_t *) aip->ai_addr);
|
||||
|
||||
if(listen_socket[listen_sockets].tcp < 0)
|
||||
if(tcp_fd < 0)
|
||||
continue;
|
||||
|
||||
listen_socket[listen_sockets].udp =
|
||||
setup_vpn_in_socket((sockaddr_t *) aip->ai_addr);
|
||||
int udp_fd = setup_vpn_in_socket((sockaddr_t *) aip->ai_addr);
|
||||
|
||||
if(listen_socket[listen_sockets].udp < 0) {
|
||||
close(listen_socket[listen_sockets].tcp);
|
||||
if(tcp_fd < 0) {
|
||||
close(tcp_fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
event_set(&listen_socket[listen_sockets].ev_tcp,
|
||||
listen_socket[listen_sockets].tcp,
|
||||
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();
|
||||
}
|
||||
io_add(&listen_socket[listen_sockets].tcp, handle_new_meta_connection, &listen_socket[listen_sockets], tcp_fd, IO_READ);
|
||||
io_add(&listen_socket[listen_sockets].udp, handle_incoming_vpn_data, &listen_socket[listen_sockets], udp_fd, IO_READ);
|
||||
|
||||
if(debug_level >= DEBUG_CONNECTIONS) {
|
||||
hostname = sockaddr2hostname((sockaddr_t *) aip->ai_addr);
|
||||
|
@ -990,10 +985,10 @@ void close_network_connections(void) {
|
|||
}
|
||||
|
||||
for(int i = 0; i < listen_sockets; i++) {
|
||||
event_del(&listen_socket[i].ev_tcp);
|
||||
event_del(&listen_socket[i].ev_udp);
|
||||
close(listen_socket[i].tcp);
|
||||
close(listen_socket[i].udp);
|
||||
io_del(&listen_socket[i].tcp);
|
||||
io_del(&listen_socket[i].udp);
|
||||
close(listen_socket[i].tcp.fd);
|
||||
close(listen_socket[i].udp.fd);
|
||||
}
|
||||
|
||||
char *envp[5];
|
||||
|
|
|
@ -271,7 +271,7 @@ int setup_vpn_in_socket(const sockaddr_t *sa) {
|
|||
return nfd;
|
||||
} /* 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);
|
||||
}
|
||||
|
||||
|
@ -281,12 +281,9 @@ void retry_outgoing(outgoing_t *outgoing) {
|
|||
if(outgoing->timeout > maxtimeout)
|
||||
outgoing->timeout = maxtimeout;
|
||||
|
||||
timeout_set(&outgoing->ev, retry_outgoing_handler, outgoing);
|
||||
event_add(&outgoing->ev, &(struct timeval){outgoing->timeout, 0});
|
||||
timeout_add(&outgoing->ev, retry_outgoing_handler, outgoing, &(struct timeval){outgoing->timeout, rand() % 100000});
|
||||
|
||||
logger(DEBUG_CONNECTIONS, LOG_NOTICE,
|
||||
"Trying to re-establish outgoing connection in %d seconds",
|
||||
outgoing->timeout);
|
||||
logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Trying to re-establish outgoing connection in %d seconds", outgoing->timeout);
|
||||
}
|
||||
|
||||
void finish_connecting(connection_t *c) {
|
||||
|
@ -349,9 +346,7 @@ static void do_outgoing_pipe(connection_t *c, char *command) {
|
|||
#endif
|
||||
}
|
||||
|
||||
static void handle_meta_write(int sock, short events, void *data) {
|
||||
connection_t *c = data;
|
||||
|
||||
static void handle_meta_write(connection_t *c) {
|
||||
ssize_t outlen = send(c->socket, c->outbuf.data + c->outbuf.offset, c->outbuf.len - c->outbuf.offset, 0);
|
||||
if(outlen <= 0) {
|
||||
if(!errno || errno == EPIPE) {
|
||||
|
@ -368,10 +363,16 @@ static void handle_meta_write(int sock, short events, void *data) {
|
|||
}
|
||||
|
||||
buffer_read(&c->outbuf, outlen);
|
||||
if(!c->outbuf.len && event_initialized(&c->outevent))
|
||||
event_del(&c->outevent);
|
||||
if(!c->outbuf.len)
|
||||
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) {
|
||||
char *address, *port, *space;
|
||||
|
@ -487,16 +488,13 @@ begin:
|
|||
|
||||
connection_add(c);
|
||||
|
||||
event_set(&c->inevent, c->socket, EV_READ | EV_PERSIST, handle_meta_connection_data, c);
|
||||
event_set(&c->outevent, c->socket, EV_WRITE | EV_PERSIST, handle_meta_write, c);
|
||||
event_add(&c->inevent, NULL);
|
||||
io_add(&c->io, handle_meta_io, c, c->socket, IO_READ);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void setup_outgoing_connection(outgoing_t *outgoing) {
|
||||
if(event_initialized(&outgoing->ev))
|
||||
event_del(&outgoing->ev);
|
||||
timeout_del(&outgoing->ev);
|
||||
|
||||
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
|
||||
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;
|
||||
sockaddr_t sa;
|
||||
int fd;
|
||||
socklen_t len = sizeof sa;
|
||||
|
||||
fd = accept(sock, &sa.sa, &len);
|
||||
fd = accept(l->tcp.fd, &sa.sa, &len);
|
||||
|
||||
if(fd < 0) {
|
||||
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);
|
||||
|
||||
event_set(&c->inevent, c->socket, EV_READ | EV_PERSIST, handle_meta_connection_data, c);
|
||||
event_set(&c->outevent, c->socket, EV_WRITE | EV_PERSIST, handle_meta_write, c);
|
||||
event_add(&c->inevent, NULL);
|
||||
io_add(&c->io, handle_meta_io, c, c->socket, IO_READ);
|
||||
|
||||
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) {
|
||||
if(event_initialized(&outgoing->ev))
|
||||
event_del(&outgoing->ev);
|
||||
timeout_del(&outgoing->ev);
|
||||
|
||||
if(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) {
|
||||
struct addrinfo *ai, hint = {0};
|
||||
sockaddr_t result;
|
||||
sockaddr_t result = {{0}};
|
||||
int err;
|
||||
|
||||
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);
|
||||
sptps_stop(&n->sptps);
|
||||
|
||||
if(timeout_initialized(&n->mtuevent))
|
||||
event_del(&n->mtuevent);
|
||||
timeout_del(&n->mtutimeout);
|
||||
|
||||
if(n->hostname)
|
||||
free(n->hostname);
|
||||
|
@ -129,6 +128,13 @@ void update_node_udp(node_t *n, const sockaddr_t *sa) {
|
|||
|
||||
if(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);
|
||||
free(n->hostname);
|
||||
n->hostname = sockaddr2hostname(&n->address);
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "cipher.h"
|
||||
#include "connection.h"
|
||||
#include "digest.h"
|
||||
#include "event.h"
|
||||
#include "subnet.h"
|
||||
|
||||
typedef struct node_status_t {
|
||||
|
@ -83,7 +84,7 @@ typedef struct node_t {
|
|||
length_t minmtu; /* Probed minimum MTU */
|
||||
length_t maxmtu; /* Probed maximum MTU */
|
||||
int mtuprobes; /* Number of probes */
|
||||
struct event mtuevent; /* Probe event */
|
||||
timeout_t mtutimeout; /* Probe event */
|
||||
|
||||
uint64_t in_packets;
|
||||
uint64_t in_bytes;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "control.h"
|
||||
#include "device.h"
|
||||
#include "edge.h"
|
||||
#include "event.h"
|
||||
#include "logger.h"
|
||||
#include "net.h"
|
||||
#include "node.h"
|
||||
|
@ -127,7 +128,7 @@ DWORD WINAPI controlhandler(DWORD request, DWORD type, LPVOID boe, LPVOID bah) {
|
|||
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
event_loopexit(NULL);
|
||||
event_exit();
|
||||
status.dwWaitHint = 30000;
|
||||
status.dwCurrentState = SERVICE_STOP_PENDING;
|
||||
SetServiceStatus(statushandle, &status);
|
||||
|
|
|
@ -165,7 +165,24 @@ static void free_past_request(past_request_t *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) {
|
||||
past_request_t *new, p = {NULL};
|
||||
|
@ -180,39 +197,17 @@ bool seen_request(const char *request) {
|
|||
new->request = xstrdup(request);
|
||||
new->firstseen = time(NULL);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
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) {
|
||||
splay_delete_tree(past_request_tree);
|
||||
|
||||
if(timeout_initialized(&past_request_event))
|
||||
event_del(&past_request_event);
|
||||
timeout_del(&past_request_timeout);
|
||||
}
|
||||
|
|
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))
|
||||
#endif
|
||||
|
||||
static struct event age_subnets_event;
|
||||
static timeout_t age_subnets_timeout;
|
||||
|
||||
/* RFC 1071 */
|
||||
|
||||
|
@ -84,13 +84,12 @@ static uint16_t inet_checksum(void *data, int len, uint16_t prevsum) {
|
|||
static bool ratelimit(int frequency) {
|
||||
static time_t lasttime = 0;
|
||||
static int count = 0;
|
||||
time_t now = time(NULL);
|
||||
|
||||
if(lasttime == now) {
|
||||
if(lasttime == now.tv_sec) {
|
||||
if(count >= frequency)
|
||||
return true;
|
||||
} else {
|
||||
lasttime = now;
|
||||
lasttime = now.tv_sec;
|
||||
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;
|
||||
|
||||
/* Find TCP header */
|
||||
int start = 0;
|
||||
int start = ether_size;
|
||||
uint16_t type = packet->data[12] << 8 | packet->data[13];
|
||||
|
||||
if(type == ETH_P_IP && packet->data[23] == 6)
|
||||
start = 14 + (packet->data[14] & 0xf) * 4;
|
||||
else if(type == ETH_P_IPV6 && packet->data[20] == 6)
|
||||
start = 14 + 40;
|
||||
if(type == ETH_P_8021Q) {
|
||||
start += 4;
|
||||
type = packet->data[16] << 8 | packet->data[17];
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
static void age_subnets(int fd, short events, void *data) {
|
||||
static void age_subnets(void *data) {
|
||||
bool left = false;
|
||||
time_t now = time(NULL);
|
||||
|
||||
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) {
|
||||
char netstr[MAXNETSTR];
|
||||
if(net2str(netstr, sizeof netstr, s))
|
||||
|
@ -209,7 +214,7 @@ static void age_subnets(int fd, short events, void *data) {
|
|||
}
|
||||
|
||||
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) {
|
||||
|
@ -236,9 +241,7 @@ static void learn_mac(mac_t *address) {
|
|||
if(c->status.active)
|
||||
send_add_subnet(c, subnet);
|
||||
|
||||
if(!timeout_initialized(&age_subnets_event))
|
||||
timeout_set(&age_subnets_event, age_subnets, NULL);
|
||||
event_add(&age_subnets_event, &(struct timeval){10, 0});
|
||||
timeout_add(&age_subnets_timeout, age_subnets, NULL, &(struct timeval){10, rand() % 100000});
|
||||
} else {
|
||||
if(subnet->expires)
|
||||
subnet->expires = time(NULL) + macexpire;
|
||||
|
@ -247,7 +250,7 @@ static void learn_mac(mac_t *address) {
|
|||
|
||||
/* 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 icmp icmp = {0};
|
||||
|
||||
|
@ -320,7 +323,7 @@ static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, uint8_t
|
|||
|
||||
/* 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;
|
||||
vpn_packet_t fragment;
|
||||
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[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;
|
||||
}
|
||||
|
||||
|
@ -394,10 +397,10 @@ static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) {
|
|||
}
|
||||
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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) {
|
||||
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) {
|
||||
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 {
|
||||
fragment_ipv4_packet(via, packet);
|
||||
fragment_ipv4_packet(via, packet, ether_size);
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -445,7 +448,7 @@ static void route_ipv4(node_t *source, vpn_packet_t *packet) {
|
|||
|
||||
/* 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 icmp6_hdr icmp6 = {0};
|
||||
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[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;
|
||||
}
|
||||
|
||||
|
@ -553,10 +556,10 @@ static void route_ipv6_unicast(node_t *source, vpn_packet_t *packet) {
|
|||
}
|
||||
|
||||
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)
|
||||
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;
|
||||
|
||||
|
@ -566,12 +569,12 @@ static void route_ipv6_unicast(node_t *source, vpn_packet_t *packet) {
|
|||
}
|
||||
|
||||
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) {
|
||||
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);
|
||||
route_ipv6_unreachable(source, packet, ICMP6_PACKET_TOO_BIG, 0);
|
||||
route_ipv6_unreachable(source, packet, ether_size, ICMP6_PACKET_TOO_BIG, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -842,17 +845,24 @@ static void route_mac(node_t *source, vpn_packet_t *packet) {
|
|||
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);
|
||||
uint16_t type = packet->data[12] << 8 | packet->data[13];
|
||||
if(type == ETH_P_IP && packet->len > 590) {
|
||||
if(packet->data[20] & 0x40) {
|
||||
length_t ethlen = 14;
|
||||
|
||||
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;
|
||||
route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED);
|
||||
route_ipv4_unreachable(source, packet, ethlen, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED);
|
||||
} else {
|
||||
fragment_ipv4_packet(via, packet);
|
||||
fragment_ipv4_packet(via, packet, ethlen);
|
||||
}
|
||||
return;
|
||||
} else if(type == ETH_P_IPV6 && packet->len > 1294) {
|
||||
} else if(type == ETH_P_IPV6 && packet->len > 1280 + ethlen) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -881,42 +891,48 @@ static void send_pcap(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];
|
||||
length_t ethlen = ether_size;
|
||||
|
||||
if(type == ETH_P_8021Q) {
|
||||
type = packet->data[16] << 8 | packet->data[17];
|
||||
ethlen += 4;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case ETH_P_IP:
|
||||
if(!checklength(source, packet, 14 + 32))
|
||||
if(!checklength(source, packet, ethlen + ip_size))
|
||||
return false;
|
||||
|
||||
if(packet->data[22] < 1) {
|
||||
if(packet->data[25] != IPPROTO_ICMP || packet->data[46] != ICMP_TIME_EXCEEDED)
|
||||
route_ipv4_unreachable(source, packet, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL);
|
||||
if(packet->data[ethlen + 8] < 1) {
|
||||
if(packet->data[ethlen + 11] != IPPROTO_ICMP || packet->data[ethlen + 32] != ICMP_TIME_EXCEEDED)
|
||||
route_ipv4_unreachable(source, packet, ethlen, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t old = packet->data[22] << 8 | packet->data[23];
|
||||
packet->data[22]--;
|
||||
uint16_t new = packet->data[22] << 8 | packet->data[23];
|
||||
uint16_t old = packet->data[ethlen + 8] << 8 | packet->data[ethlen + 9];
|
||||
packet->data[ethlen + 8]--;
|
||||
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);
|
||||
while(checksum >> 16)
|
||||
checksum = (checksum & 0xFFFF) + (checksum >> 16);
|
||||
packet->data[24] = checksum >> 8;
|
||||
packet->data[25] = checksum & 0xff;
|
||||
packet->data[ethlen + 10] = checksum >> 8;
|
||||
packet->data[ethlen + 11] = checksum & 0xff;
|
||||
|
||||
return true;
|
||||
|
||||
case ETH_P_IPV6:
|
||||
if(!checklength(source, packet, 14 + 40))
|
||||
if(!checklength(source, packet, ethlen + ip6_size))
|
||||
return false;
|
||||
|
||||
if(packet->data[21] < 1) {
|
||||
if(packet->data[20] != IPPROTO_ICMPV6 || packet->data[54] != ICMP6_TIME_EXCEEDED)
|
||||
route_ipv6_unreachable(source, packet, ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_TRANSIT);
|
||||
if(packet->data[ethlen + 7] < 1) {
|
||||
if(packet->data[ethlen + 6] != IPPROTO_ICMPV6 || packet->data[ethlen + 40] != ICMP6_TIME_EXCEEDED)
|
||||
route_ipv6_unreachable(source, packet, ethlen, ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_TRANSIT);
|
||||
return false;
|
||||
}
|
||||
|
||||
packet->data[21]--;
|
||||
packet->data[ethlen + 7]--;
|
||||
|
||||
return true;
|
||||
|
||||
|
|
|
@ -398,6 +398,8 @@ splay_node_t *splay_insert_node(splay_tree_t *tree, splay_node_t *node) {
|
|||
splay_node_t *closest;
|
||||
int result;
|
||||
|
||||
node->left = node->right = node->parent = node->next = node->prev = NULL;
|
||||
|
||||
if(!tree->root)
|
||||
splay_insert_top(tree, node);
|
||||
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) {
|
||||
node->prev = node->next = node->left = node->right = node->parent = NULL;
|
||||
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) {
|
||||
|
@ -446,6 +449,7 @@ void splay_insert_before(splay_tree_t *tree, splay_node_t *before, splay_node_t
|
|||
|
||||
node->parent = NULL;
|
||||
tree->root = node;
|
||||
tree->count++;
|
||||
}
|
||||
|
||||
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;
|
||||
tree->root = node;
|
||||
tree->count++;
|
||||
}
|
||||
|
||||
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 {
|
||||
tree->root = NULL;
|
||||
}
|
||||
|
||||
tree->count--;
|
||||
}
|
||||
|
||||
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_action_t delete;
|
||||
|
||||
int count;
|
||||
|
||||
} splay_tree_t;
|
||||
|
||||
/* (De)constructors */
|
||||
|
|
|
@ -29,6 +29,7 @@ bool send_request(void *c, const char *msg, ...) { return false; }
|
|||
struct list_t *connection_list = NULL;
|
||||
bool send_meta(void *c, const char *msg , int len) { return false; }
|
||||
char *logfilename = NULL;
|
||||
struct timeval now;
|
||||
|
||||
ecdsa_t mykey, hiskey;
|
||||
|
||||
|
|
|
@ -57,11 +57,12 @@ static char *name = NULL;
|
|||
static char *identname = NULL; /* program name for syslog */
|
||||
static char *pidfilename = NULL; /* pid file location */
|
||||
static char *confdir = NULL;
|
||||
static char controlcookie[1024];
|
||||
static char controlcookie[1025];
|
||||
char *netname = NULL;
|
||||
char *confbase = NULL;
|
||||
static char *tinc_conf = NULL;
|
||||
static char *hosts_dir = NULL;
|
||||
struct timeval now;
|
||||
|
||||
// Horrible global variables...
|
||||
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-ecdsa-keys Generate a new ECDSA public/private keypair.\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"
|
||||
" subnets - all known subnets in the VPN\n"
|
||||
" connections - all meta connections with ourself\n"
|
||||
|
@ -708,8 +709,8 @@ static bool connect_tincd(bool verbose) {
|
|||
return false;
|
||||
}
|
||||
|
||||
char host[128];
|
||||
char port[128];
|
||||
char host[129];
|
||||
char port[129];
|
||||
|
||||
if(fscanf(f, "%20d %1024s %128s port %128s", &pid, controlcookie, host, port) != 4) {
|
||||
if(verbose)
|
||||
|
@ -911,6 +912,19 @@ static int cmd_reload(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) {
|
||||
fprintf(stderr, "Invalid number of arguments.\n");
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
|
||||
memcpy(&status, &status_int, sizeof status);
|
||||
|
||||
if(do_graph) {
|
||||
memcpy(&status, &status_int, sizeof status);
|
||||
const char *color = "black";
|
||||
if(!strcmp(host, "MYSELF"))
|
||||
color = "green";
|
||||
|
@ -1000,6 +1016,8 @@ static int cmd_dump(int argc, char *argv[]) {
|
|||
color = "green";
|
||||
printf(" %s [label = \"%s\", color = \"%s\"%s];\n", node, node, color, strcmp(host, "MYSELF") ? "" : ", style = \"filled\"");
|
||||
} 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",
|
||||
node, host, port, cipher, digest, maclength, compression, options, status_int, nexthop, via, distance, pmtu, minmtu, maxmtu);
|
||||
}
|
||||
|
@ -1233,6 +1251,7 @@ static struct {
|
|||
} const variables[] = {
|
||||
/* Server configuration */
|
||||
{"AddressFamily", VAR_SERVER},
|
||||
{"AutoConnect", VAR_SERVER},
|
||||
{"BindToAddress", VAR_SERVER | VAR_MULTIPLE},
|
||||
{"BindToInterface", 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) {
|
||||
const char *matches[] = {"nodes", "edges", "subnets", "connections", "graph", NULL};
|
||||
const char *matches[] = {"reachable", "nodes", "edges", "subnets", "connections", "graph", NULL};
|
||||
static int i;
|
||||
|
||||
if(!state)
|
||||
|
|
|
@ -450,11 +450,6 @@ int main2(int argc, char **argv) {
|
|||
}
|
||||
#endif
|
||||
|
||||
if(!event_init()) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error initializing libevent!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Setup sockets and open device. */
|
||||
|
||||
if(!setup_network())
|
||||
|
|
198
src/top.c
198
src/top.c
|
@ -57,11 +57,13 @@ static int sortmode = 0;
|
|||
static bool cumulative = false;
|
||||
|
||||
static list_t node_list;
|
||||
static struct timeval now, prev, diff;
|
||||
static struct timeval cur, prev, diff;
|
||||
static int delay = 1000;
|
||||
static bool changed = true;
|
||||
static const char *unit = "bytes";
|
||||
static float scale = 1;
|
||||
static const char *bunit = "bytes";
|
||||
static float bscale = 1;
|
||||
static const char *punit = "pkts";
|
||||
static float pscale = 1;
|
||||
|
||||
#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)
|
||||
|
@ -69,10 +71,10 @@ static float scale = 1;
|
|||
|
||||
static void update(int fd) {
|
||||
sendline(fd, "%d %d", CONTROL, REQ_DUMP_TRAFFIC);
|
||||
gettimeofday(&now, NULL);
|
||||
gettimeofday(&cur, NULL);
|
||||
|
||||
timersub(&now, &prev, &diff);
|
||||
prev = now;
|
||||
timersub(&cur, &prev, &diff);
|
||||
prev = cur;
|
||||
float interval = diff.tv_sec + diff.tv_usec * 1e-6;
|
||||
|
||||
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) {
|
||||
erase();
|
||||
|
||||
mvprintw(0, 0, "Tinc %-16s Nodes: %4d Sort: %-10s %s", netname ?: "", node_list.count, sortname[sortmode], cumulative ? "Cumulative" : "Current");
|
||||
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);
|
||||
|
||||
static nodestats_t **sorted = 0;
|
||||
|
@ -157,63 +216,6 @@ static void redraw(void) {
|
|||
for(int i = 0; i < n; 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);
|
||||
|
||||
for(int i = 0, row = 3; i < n; i++, row++) {
|
||||
|
@ -228,10 +230,10 @@ static void redraw(void) {
|
|||
|
||||
if(cumulative)
|
||||
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
|
||||
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);
|
||||
|
@ -262,45 +264,53 @@ void top(int fd) {
|
|||
break;
|
||||
}
|
||||
case 'c':
|
||||
cumulative = !cumulative;
|
||||
break;
|
||||
cumulative = !cumulative;
|
||||
break;
|
||||
case 'n':
|
||||
sortmode = 0;
|
||||
break;
|
||||
sortmode = 0;
|
||||
break;
|
||||
case 'i':
|
||||
sortmode = 2;
|
||||
break;
|
||||
sortmode = 2;
|
||||
break;
|
||||
case 'I':
|
||||
sortmode = 1;
|
||||
break;
|
||||
sortmode = 1;
|
||||
break;
|
||||
case 'o':
|
||||
sortmode = 4;
|
||||
break;
|
||||
sortmode = 4;
|
||||
break;
|
||||
case 'O':
|
||||
sortmode = 3;
|
||||
break;
|
||||
sortmode = 3;
|
||||
break;
|
||||
case 't':
|
||||
sortmode = 6;
|
||||
break;
|
||||
sortmode = 6;
|
||||
break;
|
||||
case 'T':
|
||||
sortmode = 5;
|
||||
break;
|
||||
sortmode = 5;
|
||||
break;
|
||||
case 'b':
|
||||
unit = "bytes";
|
||||
scale = 1;
|
||||
break;
|
||||
bunit = "bytes";
|
||||
bscale = 1;
|
||||
punit = "pkts";
|
||||
pscale = 1;
|
||||
break;
|
||||
case 'k':
|
||||
unit = "kbyte";
|
||||
scale = 1e-3;
|
||||
break;
|
||||
bunit = "kbyte";
|
||||
bscale = 1e-3;
|
||||
punit = "pkts";
|
||||
pscale = 1;
|
||||
break;
|
||||
case 'M':
|
||||
unit = "Mbyte";
|
||||
scale = 1e-6;
|
||||
break;
|
||||
bunit = "Mbyte";
|
||||
bscale = 1e-6;
|
||||
punit = "kpkt";
|
||||
pscale = 1e-3;
|
||||
break;
|
||||
case 'G':
|
||||
unit = "Gbyte";
|
||||
scale = 1e-9;
|
||||
break;
|
||||
bunit = "Gbyte";
|
||||
bscale = 1e-9;
|
||||
punit = "Mpkt";
|
||||
pscale = 1e-6;
|
||||
break;
|
||||
case 'q':
|
||||
case KEY_BREAK:
|
||||
running = false;
|
||||
|
|
Loading…
Reference in a new issue