From bc8ca6565352276ec40b5ac02f936060b53d296b Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Mon, 26 Aug 2019 13:44:52 +0200 Subject: [PATCH] Import Upstream version 1.1~pre15 --- COPYING | 2 +- ChangeLog | 105 +++++++++++++ INSTALL | 316 +++++++++++++++++++-------------------- Makefile.in | 12 +- NEWS | 25 +++- README | 6 +- aclocal.m4 | 44 +++--- config.guess | 28 ++-- config.h.in | 6 +- config.sub | 22 ++- configure | 26 ++-- depcomp | 6 +- doc/Makefile.in | 4 +- doc/sample-config.tar.gz | Bin 1228 -> 1242 bytes doc/tinc.conf.5.in | 14 +- doc/tinc.info | 266 ++++++++++++++++---------------- doc/tinc.texi | 21 ++- gui/Makefile.in | 4 +- m4/openssl.m4 | 2 +- src/Makefile.am | 9 +- src/Makefile.in | 163 ++++++++++---------- src/autoconnect.c | 174 +++++++++++++++++++++ src/autoconnect.h | 25 ++++ src/bsd/device.c | 13 +- src/cipher.h | 4 +- src/connection.h | 2 + src/device.h | 1 + src/digest.h | 3 +- src/dropin.c | 3 +- src/ed25519/add_scalar.c | 56 ------- src/ed25519/ed25519.h | 1 - src/ed25519/sc.c | 24 --- src/ethernet.h | 13 ++ src/event.c | 7 +- src/fd_device.c | 123 +++++++++++++++ src/fsck.c | 9 +- src/graph.c | 23 ++- src/ifconfig.c | 47 +++--- src/info.c | 12 +- src/invitation.c | 39 +++-- src/linux/device.c | 3 + src/logger.c | 4 +- src/logger.h | 4 +- src/meta.c | 14 ++ src/mingw/device.c | 24 ++- src/names.c | 5 +- src/names.h | 3 +- src/net.c | 107 +------------ src/net.h | 3 +- src/net_packet.c | 12 +- src/net_setup.c | 41 ++--- src/net_socket.c | 33 ++-- src/node.c | 4 +- src/openssl/cipher.c | 28 +++- src/openssl/digest.c | 6 +- src/protocol.h | 3 +- src/protocol_auth.c | 58 +++++-- src/protocol_edge.c | 115 +++++++------- src/protocol_key.c | 6 +- src/protocol_misc.c | 7 +- src/route.c | 15 +- src/script.c | 64 +++++++- src/script.h | 16 +- src/solaris/device.c | 44 ++++-- src/sptps_test.c | 17 ++- src/subnet.c | 35 ++--- src/subnet_parse.c | 2 +- src/tincctl.c | 51 ++++--- src/tincd.c | 3 + src/top.c | 42 ++++-- src/uml_device.c | 4 +- src/upnp.c | 2 +- systemd/Makefile.in | 4 +- systemd/tinc@.service | 1 + test/Makefile.am | 2 + test/Makefile.in | 6 +- test/executables.test | 4 +- test/invite-join.test | 2 - test/invite-offline.test | 50 +++++++ test/invite-tinc-up.test | 2 +- test/ns-ping.test | 2 +- test/pong.c | 6 +- test/scripts.test | 112 ++++++++++++++ test/sptps-basic.test | 16 +- test/testlib.sh | 16 +- 85 files changed, 1687 insertions(+), 971 deletions(-) create mode 100644 src/autoconnect.c create mode 100644 src/autoconnect.h delete mode 100644 src/ed25519/add_scalar.c create mode 100644 src/fd_device.c create mode 100755 test/invite-offline.test create mode 100755 test/scripts.test diff --git a/COPYING b/COPYING index 513da31..c7a4498 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (C) 1998-2016 Ivo Timmermans, Guus Sliepen and others. +Copyright (C) 1998-2017 Ivo Timmermans, Guus Sliepen and others. See the AUTHORS file for a complete list. This program is free software; you can redistribute it and/or modify it under diff --git a/ChangeLog b/ChangeLog index 29e545f..59667bf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,108 @@ +Version 1.1pre15 September 02 2017 +------------------------------------------------------------------------ + +Guus Sliepen (56): + Preserve IPv6 scope_id in edges. + Fix the previous commit. + Ensure compatibility with OpenSSL 1.1.0. + Add -Wall to CFLAGS. + Check return value of RSA_generate_key_ex(). + Use EVP_MD_CTX_destroy() instead of _free(). + Force nul-termination of strings after vsnprintf(). + Fix warnings from the Clang static analyzer. + Fix potential memory leaks found by the Clang static analyzer. + Add missing m4 files. + Fix compiling with OpenSSL < 1.1.0. + Log warnings about dropped packets only with debug level 5 or higher. + Use AES256 and SHA256 by default for the legacy protocol. + Enforce maximum amount of bytes sent/received on meta-connections. + Fix potential segfault in the replacement vasprintf() function. + Don't build sptps_* binaries by default. + Remove the description of the LocalDiscoveryAddress option from the manual. + Use free_known_addresses() to free memory allocated by get_known_addresses(). + Add missing #defines used by fd_device.c. + Don't try to use kill() on Windows. + Merge remote-tracking branch 'dechamps/sleep' into 1.1 + Put script environment creation/deletion in functions. + Add DEBUG environment variable for scripts. + Use unique ports for all tests. + Remove superfluous sleep command in invite-join test. + Add the invite-offline test. + Update .gitignore. + Add the scripts test. + Ensure proper logging in the invite-offline test. + Use 127.0.0.1 instead of localhost to ensure tests are reproducible. + Ensure sptps_keypair and sptps_test get build for make check. + Use /dev/udp instead of /dev/ip on Solaris. + Use getmsg()/putmsg() instead of read()/write() on Solaris. + Ensure tests compile on *BSD. + Make sure realname is always initialized. + Fix compiler warnings on *BSD. + Fix segfault when adding environment variables. + Fix tests on *BSD. + Add missing tinc stop command to the scripts test. + Remove dead stores. + Add field widths to sscanf() calls. + Fix some minor issues found by cppcheck. + Remove unused add_scalar function. + Move logging of "would block" messages to debug level 4. + Set KillMode=mixed in the systemd service file. + Add configurable experation time for invitations. + Store the invitation data after a succesful join. + Forward-port tinc 1.0's handling of device errors. + Make autoconnect try to heal network splits. + Add missing break statements. + Force IPv4 for sptps-basic.test. + Fix a compiler warning. + Fix a file descriptor leak when using an invitation. + Ensure packet priority is cleared when sending PMTU probe replies. + Drop h and hh length modifiers from printf format strings. + Releasing 1.1pre15. + +Etienne Dechamps (7): + Fix error handling when setting up the UDP socket. + Fix crash on Windows when a socket is available for both write and read. + On Windows, don't cancel I/O when disabling the device. + Fix edge local addresses not being set when connections are established. + Fix edge updates containing local address changes. + Clarify the flow of add_edge_h(). + Fix address memory leaks in add_edge_h(). + +thorkill (4): + Send PKT_PROBE only when handshake has been done already. + Prevent tincd from sending packets to unexpecting nodes + Sanitize input in id_h - prevent integer overflows + Fix NULL pointer dereference in send_udp_info + +Sean McVeigh (2): + check for daemon pid existence before trying to connect to the control socket, and clean up stale files otherwise. + fix check in cmd_pid() for failure to connect to tincd + +Vittorio G (VittGam) (2): + fsck: Fix ed25519 public key reading, and fclose usage. + tincctl: Avoid falling back to 1024 bits RSA key generation when an invalid key size is specified. + +Dennis Lan (1): + Fix typo in src/upnp.c. + +Pacien TRAN-GIRARD (1): + Add fd_device + +Roman Savelyev (1): + Fix lost pointer trails in get_known_addresses(). + +Vittorio Gambaletta (VittGam) (1): + route: Support ToS/DiffServ priority inheritance when routing IPv6 packets. + +lemoer (1): + Added comments and unfold deep "if"-construct in timeout_handler + +pacien (1): + Add LogLevel config option + +volth (1): + Avoid infinite loop on EBADFD + Version 1.1pre14 May 01 2016 ------------------------------------------------------------------------ diff --git a/INSTALL b/INSTALL index 2099840..8865734 100644 --- a/INSTALL +++ b/INSTALL @@ -1,8 +1,8 @@ Installation Instructions ************************* -Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation, -Inc. + Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software +Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright @@ -12,97 +12,96 @@ without warranty of any kind. Basic Installation ================== - Briefly, the shell command `./configure && make && make install' + Briefly, the shell command './configure && make && make install' should configure, build, and install this package. The following -more-detailed instructions are generic; see the `README' file for +more-detailed instructions are generic; see the 'README' file for instructions specific to this package. Some packages provide this -`INSTALL' file but do not implement all of the features documented +'INSTALL' file but do not implement all of the features documented below. The lack of an optional feature in a given package is not necessarily a bug. More recommendations for GNU packages can be found in *note Makefile Conventions: (standards)Makefile Conventions. - The `configure' shell script attempts to guess correct values for + The 'configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that +those values to create a 'Makefile' in each directory of the package. +It may also create one or more '.h' files containing system-dependent +definitions. Finally, it creates a shell script 'config.status' that you can run in the future to recreate the current configuration, and a -file `config.log' containing compiler output (useful mainly for -debugging `configure'). +file 'config.log' containing compiler output (useful mainly for +debugging 'configure'). - It can also use an optional file (typically called `config.cache' -and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. Caching is -disabled by default to prevent problems with accidental use of stale -cache files. + It can also use an optional file (typically called 'config.cache' and +enabled with '--cache-file=config.cache' or simply '-C') that saves the +results of its tests to speed up reconfiguring. Caching is disabled by +default to prevent problems with accidental use of stale cache files. If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can +to figure out how 'configure' could check whether to do them, and mail +diffs or instructions to the address given in the 'README' so they can be considered for the next release. If you are using the cache, and at -some point `config.cache' contains results you don't want to keep, you +some point 'config.cache' contains results you don't want to keep, you may remove or edit it. - The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You need `configure.ac' if -you want to change it or regenerate `configure' using a newer version -of `autoconf'. + The file 'configure.ac' (or 'configure.in') is used to create +'configure' by a program called 'autoconf'. You need 'configure.ac' if +you want to change it or regenerate 'configure' using a newer version of +'autoconf'. The simplest way to compile this package is: - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. + 1. 'cd' to the directory containing the package's source code and type + './configure' to configure the package for your system. - Running `configure' might take a while. While running, it prints + Running 'configure' might take a while. While running, it prints some messages telling which features it is checking for. - 2. Type `make' to compile the package. + 2. Type 'make' to compile the package. - 3. Optionally, type `make check' to run any self-tests that come with + 3. Optionally, type 'make check' to run any self-tests that come with the package, generally using the just-built uninstalled binaries. - 4. Type `make install' to install the programs and any data files and + 4. Type 'make install' to install the programs and any data files and documentation. When installing into a prefix owned by root, it is recommended that the package be configured and built as a regular - user, and only the `make install' phase executed with root + user, and only the 'make install' phase executed with root privileges. - 5. Optionally, type `make installcheck' to repeat any self-tests, but + 5. Optionally, type 'make installcheck' to repeat any self-tests, but this time using the binaries in their final installed location. This target does not install anything. Running this target as a - regular user, particularly if the prior `make install' required + regular user, particularly if the prior 'make install' required root privileges, verifies that the installation completed correctly. 6. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly + source code directory by typing 'make clean'. To also remove the + files that 'configure' created (so you can compile the package for + a different kind of computer), type 'make distclean'. There is + also a 'make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. - 7. Often, you can also type `make uninstall' to remove the installed + 7. Often, you can also type 'make uninstall' to remove the installed files again. In practice, not all packages have tested that uninstallation works correctly, even though it is required by the GNU Coding Standards. - 8. Some packages, particularly those that use Automake, provide `make + 8. Some packages, particularly those that use Automake, provide 'make distcheck', which can by used by developers to test that all other - targets like `make install' and `make uninstall' work correctly. + targets like 'make install' and 'make uninstall' work correctly. This target is generally not run by end users. Compilers and Options ===================== Some systems require unusual options for compilation or linking that -the `configure' script does not know about. Run `./configure --help' +the 'configure' script does not know about. Run './configure --help' for details on some of the pertinent environment variables. - You can give `configure' initial values for configuration parameters -by setting variables in the command line or in the environment. Here -is an example: + You can give 'configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here is +an example: ./configure CC=c99 CFLAGS=-g LIBS=-lposix @@ -113,21 +112,21 @@ Compiling For Multiple Architectures You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their -own directory. To do this, you can use GNU `make'. `cd' to the +own directory. To do this, you can use GNU 'make'. 'cd' to the directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. This -is known as a "VPATH" build. +the 'configure' script. 'configure' automatically checks for the source +code in the directory that 'configure' is in and in '..'. This is known +as a "VPATH" build. - With a non-GNU `make', it is safer to compile the package for one + With a non-GNU 'make', it is safer to compile the package for one architecture at a time in the source code directory. After you have -installed the package for one architecture, use `make distclean' before +installed the package for one architecture, use 'make distclean' before reconfiguring for another architecture. On MacOS X 10.5 and later systems, you can create libraries and executables that work on multiple system types--known as "fat" or -"universal" binaries--by specifying multiple `-arch' options to the -compiler but only a single `-arch' option to the preprocessor. Like +"universal" binaries--by specifying multiple '-arch' options to the +compiler but only a single '-arch' option to the preprocessor. Like this: ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ @@ -136,105 +135,104 @@ this: This is not guaranteed to produce working output in all cases, you may have to build one architecture at a time and combine the results -using the `lipo' tool if you have problems. +using the 'lipo' tool if you have problems. Installation Names ================== - By default, `make install' installs the package's commands under -`/usr/local/bin', include files under `/usr/local/include', etc. You -can specify an installation prefix other than `/usr/local' by giving -`configure' the option `--prefix=PREFIX', where PREFIX must be an + By default, 'make install' installs the package's commands under +'/usr/local/bin', include files under '/usr/local/include', etc. You +can specify an installation prefix other than '/usr/local' by giving +'configure' the option '--prefix=PREFIX', where PREFIX must be an absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you -pass the option `--exec-prefix=PREFIX' to `configure', the package uses +pass the option '--exec-prefix=PREFIX' to 'configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give -options like `--bindir=DIR' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. In general, the -default for these options is expressed in terms of `${prefix}', so that -specifying just `--prefix' will affect all of the other directory +options like '--bindir=DIR' to specify different values for particular +kinds of files. Run 'configure --help' for a list of the directories +you can set and what kinds of files go in them. In general, the default +for these options is expressed in terms of '${prefix}', so that +specifying just '--prefix' will affect all of the other directory specifications that were not explicitly provided. The most portable way to affect installation locations is to pass the -correct locations to `configure'; however, many packages provide one or +correct locations to 'configure'; however, many packages provide one or both of the following shortcuts of passing variable assignments to the -`make install' command line to change installation locations without +'make install' command line to change installation locations without having to reconfigure or recompile. The first method involves providing an override variable for each -affected directory. For example, `make install +affected directory. For example, 'make install prefix=/alternate/directory' will choose an alternate location for all directory configuration variables that were expressed in terms of -`${prefix}'. Any directories that were specified during `configure', -but not in terms of `${prefix}', must each be overridden at install -time for the entire installation to be relocated. The approach of -makefile variable overrides for each directory variable is required by -the GNU Coding Standards, and ideally causes no recompilation. -However, some platforms have known limitations with the semantics of -shared libraries that end up requiring recompilation when using this -method, particularly noticeable in packages that use GNU Libtool. +'${prefix}'. Any directories that were specified during 'configure', +but not in terms of '${prefix}', must each be overridden at install time +for the entire installation to be relocated. The approach of makefile +variable overrides for each directory variable is required by the GNU +Coding Standards, and ideally causes no recompilation. However, some +platforms have known limitations with the semantics of shared libraries +that end up requiring recompilation when using this method, particularly +noticeable in packages that use GNU Libtool. - The second method involves providing the `DESTDIR' variable. For -example, `make install DESTDIR=/alternate/directory' will prepend -`/alternate/directory' before all installation names. The approach of -`DESTDIR' overrides is not required by the GNU Coding Standards, and + The second method involves providing the 'DESTDIR' variable. For +example, 'make install DESTDIR=/alternate/directory' will prepend +'/alternate/directory' before all installation names. The approach of +'DESTDIR' overrides is not required by the GNU Coding Standards, and does not work on platforms that have drive letters. On the other hand, it does better at avoiding recompilation issues, and works well even -when some directory options were not specified in terms of `${prefix}' -at `configure' time. +when some directory options were not specified in terms of '${prefix}' +at 'configure' time. Optional Features ================= If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. +with an extra prefix or suffix on their names by giving 'configure' the +option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'. - Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the + Some packages pay attention to '--enable-FEATURE' options to +'configure', where FEATURE indicates an optional part of the package. +They may also pay attention to '--with-PACKAGE' options, where PACKAGE +is something like 'gnu-as' or 'x' (for the X Window System). The +'README' should mention any '--enable-' and '--with-' options that the package recognizes. - For packages that use the X Window System, `configure' can usually + For packages that use the X Window System, 'configure' can usually find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. +you can use the 'configure' options '--x-includes=DIR' and +'--x-libraries=DIR' to specify their locations. Some packages offer the ability to configure how verbose the -execution of `make' will be. For these packages, running `./configure +execution of 'make' will be. For these packages, running './configure --enable-silent-rules' sets the default to minimal output, which can be -overridden with `make V=1'; while running `./configure +overridden with 'make V=1'; while running './configure --disable-silent-rules' sets the default to verbose, which can be -overridden with `make V=0'. +overridden with 'make V=0'. Particular systems ================== - On HP-UX, the default C compiler is not ANSI C compatible. If GNU -CC is not installed, it is recommended to use the following options in + On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC +is not installed, it is recommended to use the following options in order to use an ANSI C compiler: ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" and if that doesn't work, install pre-built binaries of GCC for HP-UX. - HP-UX `make' updates targets which have the same time stamps as -their prerequisites, which makes it generally unusable when shipped -generated files such as `configure' are involved. Use GNU `make' -instead. + HP-UX 'make' updates targets which have the same time stamps as their +prerequisites, which makes it generally unusable when shipped generated +files such as 'configure' are involved. Use GNU 'make' instead. On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot -parse its `' header file. The option `-nodtk' can be used as -a workaround. If GNU CC is not installed, it is therefore recommended -to try +parse its '' header file. The option '-nodtk' can be used as a +workaround. If GNU CC is not installed, it is therefore recommended to +try ./configure CC="cc" @@ -242,26 +240,26 @@ and if that doesn't work, try ./configure CC="cc -nodtk" - On Solaris, don't put `/usr/ucb' early in your `PATH'. This + On Solaris, don't put '/usr/ucb' early in your 'PATH'. This directory contains several dysfunctional programs; working variants of -these programs are available in `/usr/bin'. So, if you need `/usr/ucb' -in your `PATH', put it _after_ `/usr/bin'. +these programs are available in '/usr/bin'. So, if you need '/usr/ucb' +in your 'PATH', put it _after_ '/usr/bin'. - On Haiku, software installed for all users goes in `/boot/common', -not `/usr/local'. It is recommended to use the following options: + On Haiku, software installed for all users goes in '/boot/common', +not '/usr/local'. It is recommended to use the following options: ./configure --prefix=/boot/common Specifying the System Type ========================== - There may be some features `configure' cannot figure out + There may be some features 'configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the -_same_ architectures, `configure' can figure that out, but if it prints +_same_ architectures, 'configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the -`--build=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name which has the form: +'--build=TYPE' option. TYPE can either be a short name for the system +type, such as 'sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM @@ -270,101 +268,101 @@ where SYSTEM can have one of these forms: OS KERNEL-OS - See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't + See the file 'config.sub' for the possible values of each field. If +'config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should -use the option `--target=TYPE' to select the type of system they will +use the option '--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will -eventually be run) with `--host=TYPE'. +eventually be run) with '--host=TYPE'. Sharing Defaults ================ - If you want to set default values for `configure' scripts to share, -you can create a site shell script called `config.site' that gives -default values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. + If you want to set default values for 'configure' scripts to share, +you can create a site shell script called 'config.site' that gives +default values for variables like 'CC', 'cache_file', and 'prefix'. +'configure' looks for 'PREFIX/share/config.site' if it exists, then +'PREFIX/etc/config.site' if it exists. Or, you can set the +'CONFIG_SITE' environment variable to the location of the site script. +A warning: not all 'configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the -environment passed to `configure'. However, some packages may run +environment passed to 'configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set -them in the `configure' command line, using `VAR=value'. For example: +them in the 'configure' command line, using 'VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc -causes the specified `gcc' to be used as the C compiler (unless it is +causes the specified 'gcc' to be used as the C compiler (unless it is overridden in the site shell script). -Unfortunately, this technique does not work for `CONFIG_SHELL' due to -an Autoconf limitation. Until the limitation is lifted, you can use -this workaround: +Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an +Autoconf limitation. Until the limitation is lifted, you can use this +workaround: CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash -`configure' Invocation +'configure' Invocation ====================== - `configure' recognizes the following options to control how it + 'configure' recognizes the following options to control how it operates. -`--help' -`-h' - Print a summary of all of the options to `configure', and exit. +'--help' +'-h' + Print a summary of all of the options to 'configure', and exit. -`--help=short' -`--help=recursive' +'--help=short' +'--help=recursive' Print a summary of the options unique to this package's - `configure', and exit. The `short' variant lists options used - only in the top level, while the `recursive' variant lists options - also present in any nested packages. + 'configure', and exit. The 'short' variant lists options used only + in the top level, while the 'recursive' variant lists options also + present in any nested packages. -`--version' -`-V' - Print the version of Autoconf used to generate the `configure' +'--version' +'-V' + Print the version of Autoconf used to generate the 'configure' script, and exit. -`--cache-file=FILE' +'--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, - traditionally `config.cache'. FILE defaults to `/dev/null' to + traditionally 'config.cache'. FILE defaults to '/dev/null' to disable caching. -`--config-cache' -`-C' - Alias for `--cache-file=config.cache'. +'--config-cache' +'-C' + Alias for '--cache-file=config.cache'. -`--quiet' -`--silent' -`-q' +'--quiet' +'--silent' +'-q' Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error + suppress all normal output, redirect it to '/dev/null' (any error messages will still be shown). -`--srcdir=DIR' +'--srcdir=DIR' Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. + 'configure' can determine that directory automatically. -`--prefix=DIR' - Use DIR as the installation prefix. *note Installation Names:: - for more details, including other options available for fine-tuning - the installation locations. +'--prefix=DIR' + Use DIR as the installation prefix. *note Installation Names:: for + more details, including other options available for fine-tuning the + installation locations. -`--no-create' -`-n' +'--no-create' +'-n' Run the configure checks, but stop before creating any output files. -`configure' also accepts some other, not widely useful, options. Run -`configure --help' for more details. +'configure' also accepts some other, not widely useful, options. Run +'configure --help' for more details. diff --git a/Makefile.in b/Makefile.in index cd24b01..f7099d2 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -540,7 +540,7 @@ distdir: $(DISTFILES) ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir @@ -566,7 +566,7 @@ dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir @@ -584,7 +584,7 @@ dist dist-all: distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ @@ -594,7 +594,7 @@ distcheck: dist *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac diff --git a/NEWS b/NEWS index 674227e..ec6add6 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,27 @@ -# Version 1.1pre13 May 1 2016 +# Version 1.1pre15 September 2 2017 + +* Detect when the machine is resuming from suspension or hibernation. +* When an old PID file is found, check whether the old daemon is still alive. +* Remember scope_id for IPv6 addresses when sending UDP packets to link-local + addresses. +* Ensure compatibility with OpenSSL 1.1. +* Only log about dropped packets with debug level 5. +* Warn when trying to generate RSA keys less than 2048 bits. +* Use AES256 and SHA256 as the default encryption and digest algorithms. +* Add DeviceType = fd to support tinc on Android without requiring root. +* Support PriorityInheritance for IPv6 packets. +* Fixes for Solaris tun/tap support. +* Add a configurable expiration time for invitations. +* Store invitation data after a succesful join. +* Exit gracefully when the tun/tap device is in a bad state. +* Add the LogLevel option. +* AutoConnect now actively tries to heal split networks. + +Thanks to Etienne Dechamps, Rafał Leśniak, Sean McVeigh, Vittorio Gambaletta, +Dennis Lan, Pacien Tran-Girard, Roman Savelyev, lemoer and volth for their +contributions to this version of tinc. + +# Version 1.1pre14 May 1 2016 * Add tinc.service back. diff --git a/README b/README index 9b29f2c..d3b8f16 100644 --- a/README +++ b/README @@ -1,7 +1,7 @@ -This is the README file for tinc version 1.1pre14. Installation +This is the README file for tinc version 1.1pre15. Installation instructions may be found in the INSTALL file. -tinc is Copyright © 1998-2016 Ivo Timmermans, Guus Sliepen , and others. +tinc is Copyright © 1998-2017 Ivo Timmermans, Guus Sliepen , and others. For a complete list of authors see the AUTHORS file. @@ -32,7 +32,7 @@ at your own risk. Compatibility ------------- -Version 1.1pre14 is compatible with 1.0pre8, 1.0 and later, but not with older +Version 1.1pre15 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 diff --git a/aclocal.m4 b/aclocal.m4 index 005ea6d..d4738fd 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.15 -*- Autoconf -*- +# generated automatically by aclocal 1.15.1 -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2017 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -20,7 +20,7 @@ You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) -# Copyright (C) 2002-2014 Free Software Foundation, Inc. +# Copyright (C) 2002-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -35,7 +35,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.15' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.15], [], +m4_if([$1], [1.15.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -51,14 +51,14 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.15])dnl +[AM_AUTOMAKE_VERSION([1.15.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -110,7 +110,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd` # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# Copyright (C) 1997-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -141,7 +141,7 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -332,7 +332,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -408,7 +408,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -605,7 +605,7 @@ for _am_header in $config_headers :; do done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -626,7 +626,7 @@ if test x"${install_sh+set}" != xset; then fi AC_SUBST([install_sh])]) -# Copyright (C) 2003-2014 Free Software Foundation, Inc. +# Copyright (C) 2003-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -647,7 +647,7 @@ AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -697,7 +697,7 @@ rm -f confinc confmf # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# Copyright (C) 1997-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -736,7 +736,7 @@ fi # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -765,7 +765,7 @@ AC_DEFUN([_AM_SET_OPTIONS], AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -812,7 +812,7 @@ AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -831,7 +831,7 @@ AC_DEFUN([AM_RUN_LOG], # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -912,7 +912,7 @@ AC_CONFIG_COMMANDS_PRE( rm -f conftest.file ]) -# Copyright (C) 2009-2014 Free Software Foundation, Inc. +# Copyright (C) 2009-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -972,7 +972,7 @@ AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1000,7 +1000,7 @@ fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2014 Free Software Foundation, Inc. +# Copyright (C) 2006-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1019,7 +1019,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2014 Free Software Foundation, Inc. +# Copyright (C) 2004-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/config.guess b/config.guess index 0967f2a..2e9ad7f 100755 --- a/config.guess +++ b/config.guess @@ -2,7 +2,7 @@ # Attempt to guess a canonical system name. # Copyright 1992-2016 Free Software Foundation, Inc. -timestamp='2016-04-02' +timestamp='2016-10-02' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -186,9 +186,12 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. + # to ELF recently (or will in the future) and ABI. case "${UNAME_MACHINE_ARCH}" in - arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax) + earm*) + os=netbsdelf + ;; + arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ @@ -997,6 +1000,9 @@ EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; + mips64el:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; openrisc*:Linux:*:*) echo or1k-unknown-linux-${LIBC} exit ;; @@ -1029,6 +1035,9 @@ EOF ppcle:Linux:*:*) echo powerpcle-unknown-linux-${LIBC} exit ;; + riscv32:Linux:*:* | riscv64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; @@ -1408,18 +1417,17 @@ esac cat >&2 < in order to provide the needed -information to handle your system. +If $0 has already been updated, send the following data and any +information you think might be pertinent to config-patches@gnu.org to +provide the necessary information to handle your system. config.guess timestamp = $timestamp diff --git a/config.h.in b/config.h.in index 2cd4574..4b6f381 100644 --- a/config.h.in +++ b/config.h.in @@ -42,9 +42,9 @@ /* Darwin (MacOS/X) */ #undef HAVE_DARWIN -/* Define to 1 if you have the declaration of `OpenSSL_add_all_algorithms', - and to 0 if you don't. */ -#undef HAVE_DECL_OPENSSL_ADD_ALL_ALGORITHMS +/* Define to 1 if you have the declaration of `OpenSSL_add_all_algorithms + EVP_aes_256_cfb', and to 0 if you don't. */ +#undef HAVE_DECL_OPENSSL_ADD_ALL_ALGORITHMS_EVP_AES_256_CFB /* Define to 1 if you have the declaration of `res_init', and to 0 if you don't. */ diff --git a/config.sub b/config.sub index 8d39c4b..dd2ca93 100755 --- a/config.sub +++ b/config.sub @@ -2,7 +2,7 @@ # Configuration validation subroutine script. # Copyright 1992-2016 Free Software Foundation, Inc. -timestamp='2016-03-30' +timestamp='2016-11-04' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -117,7 +117,7 @@ case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ - kopensolaris*-gnu* | \ + kopensolaris*-gnu* | cloudabi*-eabi* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` @@ -301,6 +301,7 @@ case $basic_machine in | open8 | or1k | or1knd | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pru \ | pyramid \ | riscv32 | riscv64 \ | rl78 | rx \ @@ -428,6 +429,7 @@ case $basic_machine in | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pru-* \ | pyramid-* \ | riscv32-* | riscv64-* \ | rl78-* | romp-* | rs6000-* | rx-* \ @@ -643,6 +645,14 @@ case $basic_machine in basic_machine=m68k-bull os=-sysv3 ;; + e500v[12]) + basic_machine=powerpc-unknown + os=$os"spe" + ;; + e500v[12]-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + os=$os"spe" + ;; ebmon29k) basic_machine=a29k-amd os=-ebmon @@ -1022,7 +1032,7 @@ case $basic_machine in ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; - ppcle | powerpclittle | ppc-le | powerpc-little) + ppcle | powerpclittle) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) @@ -1032,7 +1042,7 @@ case $basic_machine in ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) + ppc64le | powerpc64little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) @@ -1389,7 +1399,7 @@ case $os in | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ @@ -1399,7 +1409,7 @@ case $os in | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ - | -onefs* | -tirtos*) + | -onefs* | -tirtos* | -phoenix* | -fuchsia*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) diff --git a/configure b/configure index be77e27..536bafc 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for tinc 1.1pre14-18-ge6497a2. +# Generated by GNU Autoconf 2.69 for tinc 1.1pre15. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -577,8 +577,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='tinc' PACKAGE_TARNAME='tinc' -PACKAGE_VERSION='1.1pre14-18-ge6497a2' -PACKAGE_STRING='tinc 1.1pre14-18-ge6497a2' +PACKAGE_VERSION='1.1pre15' +PACKAGE_STRING='tinc 1.1pre15' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1346,7 +1346,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures tinc 1.1pre14-18-ge6497a2 to adapt to many kinds of systems. +\`configure' configures tinc 1.1pre15 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1417,7 +1417,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of tinc 1.1pre14-18-ge6497a2:";; + short | recursive ) echo "Configuration of tinc 1.1pre15:";; esac cat <<\_ACEOF @@ -1556,7 +1556,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -tinc configure 1.1pre14-18-ge6497a2 +tinc configure 1.1pre15 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2021,7 +2021,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by tinc $as_me 1.1pre14-18-ge6497a2, which was +It was created by tinc $as_me 1.1pre15, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -4256,7 +4256,7 @@ fi # Define the identity of the package. PACKAGE='tinc' - VERSION='1.1pre14-18-ge6497a2' + VERSION='1.1pre15' cat >>confdefs.h <<_ACEOF @@ -7009,17 +7009,17 @@ fi done - ac_fn_c_check_decl "$LINENO" "OpenSSL_add_all_algorithms" "ac_cv_have_decl_OpenSSL_add_all_algorithms" "#include + ac_fn_c_check_decl "$LINENO" "OpenSSL_add_all_algorithms EVP_aes_256_cfb" "ac_cv_have_decl_OpenSSL_add_all_algorithms_EVP_aes_256_cfb" "#include " -if test "x$ac_cv_have_decl_OpenSSL_add_all_algorithms" = xyes; then : +if test "x$ac_cv_have_decl_OpenSSL_add_all_algorithms_EVP_aes_256_cfb" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_OPENSSL_ADD_ALL_ALGORITHMS $ac_have_decl +#define HAVE_DECL_OPENSSL_ADD_ALL_ALGORITHMS_EVP_AES_256_CFB $ac_have_decl _ACEOF if test $ac_have_decl = 1; then : @@ -7772,7 +7772,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by tinc $as_me 1.1pre14-18-ge6497a2, which was +This file was extended by tinc $as_me 1.1pre15, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -7838,7 +7838,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -tinc config.status 1.1pre14-18-ge6497a2 +tinc config.status 1.1pre15 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/depcomp b/depcomp index fc98710..b39f98f 100755 --- a/depcomp +++ b/depcomp @@ -1,9 +1,9 @@ #! /bin/sh # depcomp - compile a program generating dependencies as side-effects -scriptversion=2013-05-30.07; # UTC +scriptversion=2016-01-11.22; # UTC -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2017 Free Software Foundation, Inc. # 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 @@ -786,6 +786,6 @@ exit 0 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: diff --git a/doc/Makefile.in b/doc/Makefile.in index 3f1feb6..07a02a1 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/doc/sample-config.tar.gz b/doc/sample-config.tar.gz index 17863e9327946b62c55959b9bea0601529da8404..05b1e898092dd87c28ea91e16443fe1b45960de6 100644 GIT binary patch literal 1242 zcmV<01SR_)iwFQ-4XarI1MOLDZ`(Kw?&tgp4n1HvpmA(BFWZ2A=-Y;3yI#?B2kg^L ziJ3&GE%_ulUH<(@DOuAryWnt1?h2S_YC9q+l9C?Mj1@(hV{@q0NRC?vJE54U7sq@} zdL4g_lXlx*=X8)HNvG59rb(I}#7W%gwhy4Q8*_F;3r7~$7ee;Q`a7wH&8pn;92}4C z->iSHm#(aT8YkTY*s>YBr5C#Xhp$=#sakf@IE1^2v@nu6f<iX{T_WkMkC6KXXCr`}sMvf;zC5dYVg|-gLTsWGb zutzYc9LNz_LS~{>ugNlP?!lQEYhXn*R0vgxJfB4kQu2ZPRs8RE;~M|>L5I-yJK$&7(wKv>LBgi18xUD$ z(Aof8guq-ec-aWf3DgMVDocPhn1Lq5GLPdnYMjnxPasK;qx85P9e1K`kEgiN#;J<2 z)F%WI(gmjxGDuOXAZu&{7dR4C?il#H1Y!*qB4u>XD*AKy4Nys`!!eweMoxu8M!&^vO3~mY;TWkI{!4da{iCwc2b}JeGt9o%y($m-{G9|JKMU=`gK=nsHXpjp7(zu zzTfH`8_s`{_S&oY|G4h|?1z5jf1iMVR{s+)(4V03g4;3N%;}e6h}QQ*oEXrJLBL#6 zHs)*>%`@Q%SUFZC%ncXoj2yarMmd&5tuQn07g2^)zr04?3Le3RC6YN^o$flX7;?Fq^iCFJ++qmju*kMlPCOjF4_XE>HlZ?L2Y%8P4!=r zJjegESL6RaXnp^Gm}^VW!8_sEZvbnX&CFS!$C_%YsivB0s;Q=$YWknkcU&{@uK*|j E0NBcJAOHXW literal 1228 zcmV;-1T*^|iwFR|bm>9%M5X+Kc*=>P*$Xkn`T^7XYfPPvj ziMEMIq()M9{qJ{2%1xZOGltp5vgu$$vU#s0pNB`o%BtYqOv$mB^bU3+A<8fe=@|_Z z_Y9+c-#r^Sh@vP-`hz%%*%o8ad<_0#{Rc_(Wc}m8AUuFArm%Z?q3eGLBew&9mLB{zs5P@fNf?WQ zcRGh~H|3x?E8yw|Se|Qc45%^KsW4!L%$#ii=S)J%p*B2+bOFjvxqcWoLFcrwJ%K1b z4&vi}aGV5#A%(b6+RD02(PFGLpphztoKQlNXOxWz;DV1?U0A@dgCq$$WQ5M}om`CS zRB{WLHwK28(6+{uD=lWsa=@Xv()T#VoP$DTI7+cx8Lom(;{x-08wb(gO%MfPFYYhr zpsLeCWN^&1$nciW} z%<9f}Mzmdm-SI@9I3kGNy#41q5r(@Wiuk1x#VY+x|L__9!)Vare;;!A zs+S7cGt(8I8*UBMl>>-n736#-G9IALm4%6zaRUogyWz3sJXa-H1-Swy7YGvsBn{7* zv@jQT3c`}@XTzOIrnE+|f@CFcko7psy9PyEA~uyQIeM8fEm(?~{d9GGcX|8%^!(D{ z20@5{$zF@e)VoA;#CA#4R29r(fYKa6S|gmtm7>|;8s0hm1@gx*XPl)WMOnQRx%E)86 zn2DTt$Wx0!dnDVOkA*~H5T2`kz|pTdV(kBYJUtIROtj1xVx&X*hC$fy#B=-y^uEi-dH_+dC+5*!K4ql#rn1B3_5Qhd>f*h1iGOs8GY zVE6=#m`F4xz!|GWW{U-GM>I7Ip@)2dC#;-!45@lDb<9z+g<}swk%EFVk3@t4f`VSk zN-JU^Y&UY2ibB{0y!#o|e_Ij-F@ev@q7ogz88d`5!=(`xvHiVgaXhr9QMu)R)Iw7+ z*Q9X*?qa;O64G)_fOn|GG@Bm8F&@=_?k9_oi-A?`luCBbsYGpfF~%7!gt1(9mBeXz zXkyU%3rz#jM%}RHGD{|(bW9ZM7o4zVPgP>?Bm9!m6cE8;5w*;jBo06KQSKBLM6KJh zo=0@$T+c;OkVA6+sH5tkP7ifM=a^F}WQp(Z@gz7KT^ymlSE{8~8Y$#G;rGg~6_XcGt+digE3LHBN-M4W%jHi(!0#*oC;$Lcyk!3X diff --git a/doc/tinc.conf.5.in b/doc/tinc.conf.5.in index 783c299..cb7d1b1 100644 --- a/doc/tinc.conf.5.in +++ b/doc/tinc.conf.5.in @@ -1,4 +1,4 @@ -.Dd 2016-04-11 +.Dd 2017-09-02 .Dt TINC.CONF 5 .\" Manual page created by: .\" Ivo Timmermans @@ -234,6 +234,10 @@ 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 fd +Use a file descriptor. +All packets are read from this interface. +Packets received for the local node are written to it. .It uml Pq not compiled in by default Create a UNIX socket with the filename specified by .Va Device , @@ -323,6 +327,8 @@ 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 InvitationExpire Li = Ar seconds Pq 604800 +This option controls the period invitations are valid. .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, @@ -363,6 +369,8 @@ 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 some packets to the local address of the node during UDP discovery. This will not work with old nodes that don't transmit their local address. +.It Va LogLevel Li = level Pq 0 +This option controls the verbosity of the logging. The higher the debug level, the more messages it will log. .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 @@ -775,6 +783,10 @@ It can be used to set up the corresponding network interface. 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. +.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /invitations/ +This directory contains outstanding invitations. +.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /invitation-data +After a succesful join, this file contains a copy of the invitation data received. .El .Sh SEE ALSO .Xr tincd 8 , diff --git a/doc/tinc.info b/doc/tinc.info index 9540627..419de73 100644 --- a/doc/tinc.info +++ b/doc/tinc.info @@ -1,14 +1,14 @@ -This is tinc.info, produced by makeinfo version 6.1 from tinc.texi. +This is tinc.info, produced by makeinfo version 6.4.90 from tinc.texi. INFO-DIR-SECTION Networking tools START-INFO-DIR-ENTRY * tinc: (tinc). The tinc Manual. END-INFO-DIR-ENTRY -This is the info manual for tinc version 1.1pre11-263-g51a0dc5, a +This is the info manual for tinc version 1.1pre14-62-g958a751e, a Virtual Private Network daemon. - Copyright (C) 1998-2016 Ivo Timmermans, Guus Sliepen + Copyright (C) 1998-2017 Ivo Timmermans, Guus Sliepen and Wessel Dankers . Permission is granted to make and distribute verbatim copies of this @@ -888,6 +888,11 @@ DeviceType = (platform dependent) that this can cause decrypted VPN packets to be sent out on a real network if misconfigured. + fd + Use a file descriptor. All packets are read from this + interface. Packets received for the local node are written to + it. + uml (not compiled in by default) Create a UNIX socket with the filename specified by DEVICE, or '/var/run/NETNAME.umlsocket' if not specified. Tinc will wait @@ -1008,9 +1013,9 @@ LocalDiscovery = (no) to the local address of the node during UDP discovery. This will not work with old nodes that don't transmit their local address. -LocalDiscoveryAddress
- If this variable is specified, local discovery packets are sent to - the given ADDRESS. +LogLevel = (0) + This option controls the verbosity of the logging. See *note Debug + levels::. Mode = (router) This option selects the way packets are routed to other daemons. @@ -1039,6 +1044,9 @@ Mode = (router) every packet will be broadcast to the other daemons while no routing table is managed. +InvitationExpire = (604800) + This option controls the time invitations are valid. + KeyExpire = (3600) This option controls the time the encryption keys used to encrypt the data are valid. It is common practice to change keys at @@ -1098,7 +1106,7 @@ ProcessPriority = adjusted. Increasing the priority may help to reduce latency and packet loss on the VPN. -Proxy = socks4 | socks5 | http | exec ... [experimental] +Proxy = socks4 | socks5 | http | exec ... [experimental] Use a proxy when making outgoing connections. The following proxy types are currently supported: @@ -3397,13 +3405,13 @@ Concept Index * Digest: Host configuration variables. (line 33) * DirectOnly: Main configuration variables. - (line 169) + (line 174) * disconnect: tinc commands. (line 142) * dummy: Main configuration variables. (line 106) * dump: tinc commands. (line 95) * Ed25519PrivateKeyFile: Main configuration variables. - (line 176) + (line 181) * edit: tinc commands. (line 32) * encapsulating: The UDP tunnel. (line 30) * encryption: Encryption of network packets. @@ -3414,13 +3422,15 @@ Concept Index * exchange: tinc commands. (line 48) * exchange-all: tinc commands. (line 51) * exec: Main configuration variables. - (line 357) + (line 365) * ExperimentalProtocol: Main configuration variables. - (line 180) + (line 185) * export: tinc commands. (line 36) * export-all: tinc commands. (line 40) +* fd: Main configuration variables. + (line 129) * Forwarding: Main configuration variables. - (line 187) + (line 192) * frame type: The UDP tunnel. (line 6) * fsck: tinc commands. (line 160) * generate-ed25519-keys: tinc commands. (line 86) @@ -3429,11 +3439,11 @@ Concept Index * get: tinc commands. (line 11) * graph: tinc commands. (line 108) * Hostnames: Main configuration variables. - (line 207) + (line 212) * http: Main configuration variables. - (line 354) + (line 362) * hub: Main configuration variables. - (line 275) + (line 280) * ID: Legacy authentication protocol. (line 6) * Ifconfig: Invitation file format. @@ -3444,15 +3454,17 @@ Concept Index * info: tinc commands. (line 120) * init: tinc commands. (line 6) * Interface: Main configuration variables. - (line 218) + (line 223) * INTERFACE: Scripts. (line 75) +* InvitationExpire: Main configuration variables. + (line 285) * INVITATION_FILE: Scripts. (line 98) * INVITATION_URL: Scripts. (line 102) * invite: tinc commands. (line 54) * IRC: Contact information. (line 9) * join: tinc commands. (line 59) * KeyExpire: Main configuration variables. - (line 280) + (line 288) * KEY_CHANGED: The meta-protocol. (line 63) * legacy authentication protocol: Legacy authentication protocol. (line 6) @@ -3462,31 +3474,31 @@ Concept Index * LibreSSL: LibreSSL/OpenSSL. (line 6) * license: LibreSSL/OpenSSL. (line 38) * ListenAddress: Main configuration variables. - (line 226) + (line 231) * LocalDiscovery: Main configuration variables. - (line 238) -* LocalDiscoveryAddress: Main configuration variables. - (line 249) + (line 243) * log: tinc commands. (line 130) +* LogLevel: Main configuration variables. + (line 254) * lzo: lzo. (line 6) * MACExpire: Main configuration variables. - (line 286) + (line 294) * MACLength: Host configuration variables. (line 45) * MaxConnectionBurst: Main configuration variables. - (line 291) + (line 299) * meta-protocol: The meta-connection. (line 18) * META_KEY: Legacy authentication protocol. (line 6) * Mode: Main configuration variables. - (line 253) + (line 258) * MTUInfoInterval: Host configuration variables. (line 60) * multicast: Main configuration variables. (line 118) * multiple networks: Multiple networks. (line 6) * Name: Main configuration variables. - (line 297) + (line 305) * NAME: Scripts. (line 69) * netmask: Network interfaces. (line 39) * netname: Multiple networks. (line 6) @@ -3505,9 +3517,9 @@ Concept Index * pid: tinc commands. (line 78) * PING: The meta-protocol. (line 88) * PingInterval: Main configuration variables. - (line 308) + (line 316) * PingTimeout: Main configuration variables. - (line 312) + (line 320) * platforms: Supported platforms. (line 6) * PMTU: Host configuration variables. (line 52) @@ -3518,17 +3530,17 @@ Concept Index (line 65) * port numbers: Other files. (line 17) * PriorityInheritance: Main configuration variables. - (line 318) + (line 326) * private: Virtual Private Networks. (line 10) * PrivateKey: Main configuration variables. - (line 323) + (line 331) * PrivateKeyFile: Main configuration variables. - (line 329) + (line 337) * ProcessPriority: Main configuration variables. - (line 334) + (line 342) * Proxy: Main configuration variables. - (line 339) + (line 347) * PublicKey: Host configuration variables. (line 69) * PublicKeyFile: Host configuration variables. @@ -3541,7 +3553,7 @@ Concept Index * REMOTEADDRESS: Scripts. (line 84) * REMOTEPORT: Scripts. (line 87) * ReplayWindow: Main configuration variables. - (line 362) + (line 370) * requirements: Libraries. (line 6) * REQ_KEY: The meta-protocol. (line 63) * restart: tinc commands. (line 70) @@ -3549,7 +3561,7 @@ Concept Index * Route: Invitation file format. (line 51) * router: Main configuration variables. - (line 256) + (line 261) * runtime options: Runtime options. (line 9) * scalability: tinc. (line 19) * scripts: Scripts. (line 6) @@ -3560,21 +3572,21 @@ Concept Index * sign: tinc commands. (line 172) * signals: Signals. (line 6) * socks4: Main configuration variables. - (line 343) + (line 351) * socks5: Main configuration variables. - (line 348) + (line 356) * SPTPS: Simple Peer-to-Peer Security. (line 6) * start: tinc commands. (line 64) * stop: tinc commands. (line 67) * StrictSubnets: Main configuration variables. - (line 373) + (line 381) * Subnet: Host configuration variables. (line 84) * SUBNET: Scripts. (line 91) * SVPN: Security. (line 11) * switch: Main configuration variables. - (line 264) + (line 269) * TCP: The meta-connection. (line 10) * TCPonly: Host configuration variables. (line 113) @@ -3588,42 +3600,42 @@ Concept Index * top <1>: tinc top. (line 6) * traditional VPNs: tinc. (line 19) * tunifhead: Main configuration variables. - (line 153) + (line 158) * TunnelServer: Main configuration variables. - (line 380) + (line 388) * tunnohead: Main configuration variables. - (line 147) + (line 152) * UDP: The UDP tunnel. (line 30) * UDP <1>: Encryption of network packets. (line 11) * UDPDiscoveryInterval: Main configuration variables. - (line 400) + (line 408) * UDPDiscoveryKeepaliveInterval: Main configuration variables. - (line 394) + (line 402) * UDPDiscoveryTimeout: Main configuration variables. - (line 404) + (line 412) * UDPDiscovey: Main configuration variables. - (line 387) + (line 395) * UDPInfoInterval: Main configuration variables. - (line 409) + (line 417) * UDPRcvBuf: Main configuration variables. - (line 413) + (line 421) * UDPSndBuf: Main configuration variables. - (line 419) + (line 427) * UML: Main configuration variables. - (line 129) + (line 134) * Universal tun/tap: Configuration of Linux kernels. (line 6) * UPnP: Main configuration variables. - (line 425) + (line 433) * UPnPDiscoverWait: Main configuration variables. - (line 436) + (line 444) * UPnPRefreshPeriod: Main configuration variables. - (line 440) + (line 448) * utun: Main configuration variables. - (line 160) + (line 165) * VDE: Main configuration variables. - (line 134) + (line 139) * verify: tinc commands. (line 177) * virtual: Virtual Private Networks. (line 18) @@ -3640,78 +3652,78 @@ Concept Index  Tag Table: -Node: Top821 -Node: Introduction1157 -Node: Virtual Private Networks1961 -Node: tinc3673 -Node: Supported platforms5185 -Node: Preparations5882 -Node: Configuring the kernel6138 -Node: Configuration of Linux kernels6547 -Node: Configuration of FreeBSD kernels7396 -Node: Configuration of OpenBSD kernels7861 -Node: Configuration of NetBSD kernels8218 -Node: Configuration of Solaris kernels8620 -Node: Configuration of Darwin (MacOS/X) kernels9282 -Node: Configuration of Windows10095 -Node: Libraries10634 -Node: LibreSSL/OpenSSL11091 -Node: zlib13617 -Node: lzo14639 -Node: libcurses15630 -Node: libreadline16540 -Node: Installation17477 -Node: Building and installing tinc18381 -Node: Darwin (MacOS/X) build environment19037 -Node: Cygwin (Windows) build environment19596 -Node: MinGW (Windows) build environment20181 -Node: System files20769 -Node: Device files21034 -Node: Other files21447 -Node: Configuration22060 -Node: Configuration introduction22347 -Node: Multiple networks23868 -Node: How connections work25235 -Node: Configuration files27796 -Node: Main configuration variables29428 -Node: Host configuration variables50169 -Node: Scripts56239 -Node: How to configure60139 -Node: Network interfaces64623 -Node: Example configuration67002 -Node: Running tinc72101 -Node: Runtime options72688 -Node: Signals75548 -Node: Debug levels76397 -Node: Solving problems77333 -Node: Error messages78759 -Node: Sending bug reports83076 -Node: Controlling tinc84023 -Node: tinc runtime options84759 -Node: tinc environment variables85508 -Node: tinc commands85837 -Node: tinc examples92695 -Node: tinc top93257 -Node: Invitations94842 -Node: How invitations work95505 -Node: Invitation file format97798 -Node: Writing an invitation-created script100723 -Node: Technical information101785 -Node: The connection102015 -Node: The UDP tunnel102327 -Node: The meta-connection105372 -Node: The meta-protocol106830 -Node: Security111813 -Node: Legacy authentication protocol113150 -Node: Simple Peer-to-Peer Security117767 -Node: Encryption of network packets123412 -Node: Security issues126050 -Node: Platform specific information127797 -Node: Interface configuration128025 -Node: Routes130466 -Node: About us132377 -Node: Contact information132554 -Node: Authors132957 -Node: Concept Index133361 +Node: Top824 +Node: Introduction1160 +Node: Virtual Private Networks1964 +Node: tinc3676 +Node: Supported platforms5188 +Node: Preparations5885 +Node: Configuring the kernel6141 +Node: Configuration of Linux kernels6550 +Node: Configuration of FreeBSD kernels7399 +Node: Configuration of OpenBSD kernels7864 +Node: Configuration of NetBSD kernels8221 +Node: Configuration of Solaris kernels8623 +Node: Configuration of Darwin (MacOS/X) kernels9285 +Node: Configuration of Windows10098 +Node: Libraries10637 +Node: LibreSSL/OpenSSL11094 +Node: zlib13620 +Node: lzo14642 +Node: libcurses15633 +Node: libreadline16543 +Node: Installation17480 +Node: Building and installing tinc18384 +Node: Darwin (MacOS/X) build environment19040 +Node: Cygwin (Windows) build environment19599 +Node: MinGW (Windows) build environment20184 +Node: System files20772 +Node: Device files21037 +Node: Other files21450 +Node: Configuration22063 +Node: Configuration introduction22350 +Node: Multiple networks23871 +Node: How connections work25238 +Node: Configuration files27799 +Node: Main configuration variables29431 +Node: Host configuration variables50412 +Node: Scripts56482 +Node: How to configure60382 +Node: Network interfaces64866 +Node: Example configuration67245 +Node: Running tinc72344 +Node: Runtime options72931 +Node: Signals75791 +Node: Debug levels76640 +Node: Solving problems77576 +Node: Error messages79002 +Node: Sending bug reports83319 +Node: Controlling tinc84266 +Node: tinc runtime options85002 +Node: tinc environment variables85751 +Node: tinc commands86080 +Node: tinc examples92938 +Node: tinc top93500 +Node: Invitations95085 +Node: How invitations work95748 +Node: Invitation file format98041 +Node: Writing an invitation-created script100966 +Node: Technical information102028 +Node: The connection102258 +Node: The UDP tunnel102570 +Node: The meta-connection105615 +Node: The meta-protocol107073 +Node: Security112056 +Node: Legacy authentication protocol113393 +Node: Simple Peer-to-Peer Security118010 +Node: Encryption of network packets123655 +Node: Security issues126293 +Node: Platform specific information128040 +Node: Interface configuration128268 +Node: Routes130709 +Node: About us132620 +Node: Contact information132797 +Node: Authors133200 +Node: Concept Index133604  End Tag Table diff --git a/doc/tinc.texi b/doc/tinc.texi index cb50e74..83e42c6 100644 --- a/doc/tinc.texi +++ b/doc/tinc.texi @@ -15,7 +15,7 @@ This is the info manual for @value{PACKAGE} version @value{VERSION}, a Virtual Private Network daemon. -Copyright @copyright{} 1998-2016 Ivo Timmermans, +Copyright @copyright{} 1998-2017 Ivo Timmermans, Guus Sliepen and Wessel Dankers . @@ -43,7 +43,7 @@ permission notice identical to this one. @vskip 0pt plus 1filll This is the info manual for @value{PACKAGE} version @value{VERSION}, a Virtual Private Network daemon. -Copyright @copyright{} 1998-2016 Ivo Timmermans, +Copyright @copyright{} 1998-2017 Ivo Timmermans, Guus Sliepen and Wessel Dankers . @@ -958,6 +958,12 @@ This can be used to connect to UML, QEMU or KVM instances listening on the same Do NOT connect multiple 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. +@cindex fd +@item fd +Use a file descriptor. +All packets are read from this interface. +Packets received for the local node are written to it. + @cindex UML @item uml (not compiled in by default) Create a UNIX socket with the filename specified by @@ -1086,9 +1092,10 @@ which normally would prevent the peers from learning each other's LAN address. Currently, local discovery is implemented by sending some packets to the local address of the node during UDP discovery. This will not work with old nodes that don't transmit their local address. -@cindex LocalDiscoveryAddress -@item LocalDiscoveryAddress <@var{address}> -If this variable is specified, local discovery packets are sent to the given @var{address}. +@cindex LogLevel +@item LogLevel = <@var{level}> (0) +This option controls the verbosity of the logging. +See @ref{Debug levels}. @cindex Mode @item Mode = (router) @@ -1119,6 +1126,10 @@ every packet will be broadcast to the other daemons while no routing table is managed. @end table +@cindex InvitationExpire +@item InvitationExpire = <@var{seconds}> (604800) +This option controls the time invitations are valid. + @cindex KeyExpire @item KeyExpire = <@var{seconds}> (3600) This option controls the time the encryption keys used to encrypt the data diff --git a/gui/Makefile.in b/gui/Makefile.in index c81df2f..178c672 100644 --- a/gui/Makefile.in +++ b/gui/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/m4/openssl.m4 b/m4/openssl.m4 index 6bb33cf..4afcff2 100644 --- a/m4/openssl.m4 +++ b/m4/openssl.m4 @@ -49,7 +49,7 @@ AC_DEFUN([tinc_OPENSSL], [AC_MSG_ERROR([Missing LibreSSL/OpenSSL functionality, make sure you have installed the latest version.]); break], ) - AC_CHECK_DECLS([OpenSSL_add_all_algorithms], , + AC_CHECK_DECLS([OpenSSL_add_all_algorithms EVP_aes_256_cfb], , [AC_MSG_ERROR([Missing LibreSSL/OpenSSL functionality, make sure you have installed the latest version.]); break], [#include ] ) diff --git a/src/Makefile.am b/src/Makefile.am index 200c71f..7be46d9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,8 @@ ## Produce this file with automake to get Makefile.in -sbin_PROGRAMS = tincd tinc sptps_test sptps_keypair +sbin_PROGRAMS = tincd tinc +check_PROGRAMS = sptps_test sptps_keypair +EXTRA_PROGRAMS = sptps_test sptps_keypair CLEANFILES = version_git.h @@ -18,11 +20,10 @@ version.c: ${srcdir}/version.c endif if LINUX -sbin_PROGRAMS += sptps_speed +EXTRA_PROGRAMS += sptps_speed endif ed25519_SOURCES = \ - ed25519/add_scalar.c \ ed25519/ed25519.h \ ed25519/fe.c ed25519/fe.h \ ed25519/fixedint.h \ @@ -41,6 +42,7 @@ chacha_poly1305_SOURCES = \ chacha-poly1305/poly1305.c chacha-poly1305/poly1305.h tincd_SOURCES = \ + autoconnect.c autoconnect.h \ buffer.c buffer.h \ cipher.h \ conf.c conf.h \ @@ -58,6 +60,7 @@ tincd_SOURCES = \ edge.c edge.h \ ethernet.h \ event.c event.h \ + fd_device.c \ graph.c graph.h \ hash.c hash.h \ have.h \ diff --git a/src/Makefile.in b/src/Makefile.in index 6d5a8ce..a132cf1 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -88,8 +88,10 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -sbin_PROGRAMS = tincd$(EXEEXT) tinc$(EXEEXT) sptps_test$(EXEEXT) \ - sptps_keypair$(EXEEXT) $(am__EXEEXT_1) +sbin_PROGRAMS = tincd$(EXEEXT) tinc$(EXEEXT) +check_PROGRAMS = sptps_test$(EXEEXT) sptps_keypair$(EXEEXT) +EXTRA_PROGRAMS = sptps_test$(EXEEXT) sptps_keypair$(EXEEXT) \ + $(am__EXEEXT_1) @LINUX_TRUE@am__append_1 = sptps_speed @GETOPT_FALSE@am__append_2 = \ @GETOPT_FALSE@ getopt.c getopt.h \ @@ -216,19 +218,18 @@ CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(sbindir)" PROGRAMS = $(sbin_PROGRAMS) am__sptps_keypair_SOURCES_DIST = sptps_keypair.c utils.c utils.h \ - ed25519/ecdsagen.c ed25519/add_scalar.c ed25519/ed25519.h \ - ed25519/fe.c ed25519/fe.h ed25519/fixedint.h ed25519/ge.c \ - ed25519/ge.h ed25519/key_exchange.c ed25519/keypair.c \ + ed25519/ecdsagen.c ed25519/ed25519.h ed25519/fe.c ed25519/fe.h \ + ed25519/fixedint.h ed25519/ge.c ed25519/ge.h \ + ed25519/key_exchange.c ed25519/keypair.c \ ed25519/precomp_data.h ed25519/sc.c ed25519/sc.h \ ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ ed25519/verify.c getopt.c getopt.h getopt1.c openssl/crypto.c \ nolegacy/crypto.c am__dirstamp = $(am__leading_dot)dirstamp -am__objects_1 = ed25519/add_scalar.$(OBJEXT) ed25519/fe.$(OBJEXT) \ - ed25519/ge.$(OBJEXT) ed25519/key_exchange.$(OBJEXT) \ - ed25519/keypair.$(OBJEXT) ed25519/sc.$(OBJEXT) \ - ed25519/sha512.$(OBJEXT) ed25519/sign.$(OBJEXT) \ - ed25519/verify.$(OBJEXT) +am__objects_1 = ed25519/fe.$(OBJEXT) ed25519/ge.$(OBJEXT) \ + ed25519/key_exchange.$(OBJEXT) ed25519/keypair.$(OBJEXT) \ + ed25519/sc.$(OBJEXT) ed25519/sha512.$(OBJEXT) \ + ed25519/sign.$(OBJEXT) ed25519/verify.$(OBJEXT) @GETOPT_FALSE@am__objects_2 = getopt.$(OBJEXT) getopt1.$(OBJEXT) @OPENSSL_TRUE@am__objects_3 = openssl/crypto.$(OBJEXT) @GCRYPT_TRUE@@OPENSSL_FALSE@am__objects_4 = openssl/crypto.$(OBJEXT) @@ -241,9 +242,9 @@ sptps_keypair_OBJECTS = $(am_sptps_keypair_OBJECTS) sptps_keypair_LDADD = $(LDADD) am__sptps_speed_SOURCES_DIST = logger.c logger.h sptps.c sptps.h \ sptps_speed.c utils.c utils.h ed25519/ecdh.c ed25519/ecdsa.c \ - ed25519/ecdsagen.c ed25519/add_scalar.c ed25519/ed25519.h \ - ed25519/fe.c ed25519/fe.h ed25519/fixedint.h ed25519/ge.c \ - ed25519/ge.h ed25519/key_exchange.c ed25519/keypair.c \ + ed25519/ecdsagen.c ed25519/ed25519.h ed25519/fe.c ed25519/fe.h \ + ed25519/fixedint.h ed25519/ge.c ed25519/ge.h \ + ed25519/key_exchange.c ed25519/keypair.c \ ed25519/precomp_data.h ed25519/sc.c ed25519/sc.h \ ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ ed25519/verify.c chacha-poly1305/chacha.c \ @@ -272,11 +273,10 @@ sptps_speed_OBJECTS = $(am_sptps_speed_OBJECTS) sptps_speed_DEPENDENCIES = am__sptps_test_SOURCES_DIST = logger.c logger.h sptps.c sptps.h \ sptps_test.c utils.c utils.h ed25519/ecdh.c ed25519/ecdsa.c \ - ed25519/add_scalar.c ed25519/ed25519.h ed25519/fe.c \ - ed25519/fe.h ed25519/fixedint.h ed25519/ge.c ed25519/ge.h \ - ed25519/key_exchange.c ed25519/keypair.c \ - ed25519/precomp_data.h ed25519/sc.c ed25519/sc.h \ - ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ + ed25519/ed25519.h ed25519/fe.c ed25519/fe.h ed25519/fixedint.h \ + ed25519/ge.c ed25519/ge.h ed25519/key_exchange.c \ + ed25519/keypair.c ed25519/precomp_data.h ed25519/sc.c \ + ed25519/sc.h ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ ed25519/verify.c chacha-poly1305/chacha.c \ chacha-poly1305/chacha.h chacha-poly1305/chacha-poly1305.c \ chacha-poly1305/chacha-poly1305.h chacha-poly1305/poly1305.c \ @@ -300,11 +300,11 @@ am__tinc_SOURCES_DIST = dropin.c dropin.h fsck.c fsck.h ifconfig.c \ list.h names.c names.h netutl.c netutl.h script.c script.h \ sptps.c sptps.h subnet_parse.c subnet.h tincctl.c tincctl.h \ top.c top.h utils.c utils.h version.c version.h ed25519/ecdh.c \ - ed25519/ecdsa.c ed25519/ecdsagen.c ed25519/add_scalar.c \ - ed25519/ed25519.h ed25519/fe.c ed25519/fe.h ed25519/fixedint.h \ - ed25519/ge.c ed25519/ge.h ed25519/key_exchange.c \ - ed25519/keypair.c ed25519/precomp_data.h ed25519/sc.c \ - ed25519/sc.h ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ + ed25519/ecdsa.c ed25519/ecdsagen.c ed25519/ed25519.h \ + ed25519/fe.c ed25519/fe.h ed25519/fixedint.h ed25519/ge.c \ + ed25519/ge.h ed25519/key_exchange.c ed25519/keypair.c \ + ed25519/precomp_data.h ed25519/sc.c ed25519/sc.h \ + ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ ed25519/verify.c chacha-poly1305/chacha.c \ chacha-poly1305/chacha.h chacha-poly1305/chacha-poly1305.c \ chacha-poly1305/chacha-poly1305.h chacha-poly1305/poly1305.c \ @@ -336,23 +336,23 @@ am_tinc_OBJECTS = dropin.$(OBJEXT) fsck.$(OBJEXT) ifconfig.$(OBJEXT) \ tinc_OBJECTS = $(am_tinc_OBJECTS) am__DEPENDENCIES_1 = tinc_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -am__tincd_SOURCES_DIST = buffer.c buffer.h cipher.h conf.c conf.h \ - connection.c connection.h control.c control.h control_common.h \ - crypto.h device.h digest.h dropin.c dropin.h dummy_device.c \ - ecdh.h ecdsa.h ecdsagen.h edge.c edge.h ethernet.h event.c \ - event.h graph.c graph.h hash.c hash.h have.h ipv4.h ipv6.h \ - list.c list.h logger.c logger.h meta.c meta.h \ - multicast_device.c names.c names.h net.c net.h net_packet.c \ - net_setup.c net_socket.c netutl.c netutl.h node.c node.h prf.h \ - process.c process.h protocol.c protocol.h protocol_auth.c \ - protocol_edge.c protocol_key.c protocol_misc.c \ - protocol_subnet.c raw_socket_device.c route.c route.h rsa.h \ - rsagen.h script.c script.h splay_tree.c splay_tree.h sptps.c \ - sptps.h subnet.c subnet.h subnet_parse.c system.h tincd.c \ - utils.c utils.h xalloc.h version.c version.h ed25519/ecdh.c \ - ed25519/ecdsa.c ed25519/add_scalar.c ed25519/ed25519.h \ - ed25519/fe.c ed25519/fe.h ed25519/fixedint.h ed25519/ge.c \ - ed25519/ge.h ed25519/key_exchange.c ed25519/keypair.c \ +am__tincd_SOURCES_DIST = autoconnect.c autoconnect.h buffer.c buffer.h \ + cipher.h conf.c conf.h connection.c connection.h control.c \ + control.h control_common.h crypto.h device.h digest.h dropin.c \ + dropin.h dummy_device.c ecdh.h ecdsa.h ecdsagen.h edge.c \ + edge.h ethernet.h event.c event.h fd_device.c graph.c graph.h \ + hash.c hash.h have.h ipv4.h ipv6.h list.c list.h logger.c \ + logger.h meta.c meta.h multicast_device.c names.c names.h \ + net.c net.h net_packet.c net_setup.c net_socket.c netutl.c \ + netutl.h node.c node.h prf.h process.c process.h protocol.c \ + protocol.h protocol_auth.c protocol_edge.c protocol_key.c \ + protocol_misc.c protocol_subnet.c raw_socket_device.c route.c \ + route.h rsa.h rsagen.h script.c script.h splay_tree.c \ + splay_tree.h sptps.c sptps.h subnet.c subnet.h subnet_parse.c \ + system.h tincd.c utils.c utils.h xalloc.h version.c version.h \ + ed25519/ecdh.c ed25519/ecdsa.c ed25519/ed25519.h ed25519/fe.c \ + ed25519/fe.h ed25519/fixedint.h ed25519/ge.c ed25519/ge.h \ + ed25519/key_exchange.c ed25519/keypair.c \ ed25519/precomp_data.h ed25519/sc.c ed25519/sc.h \ ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ ed25519/verify.c chacha-poly1305/chacha.c \ @@ -384,14 +384,15 @@ am__tincd_SOURCES_DIST = buffer.c buffer.h cipher.h conf.c conf.h \ @GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/prf.$(OBJEXT) \ @GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/rsa.$(OBJEXT) @MINIUPNPC_TRUE@am__objects_23 = upnp.$(OBJEXT) -am_tincd_OBJECTS = buffer.$(OBJEXT) conf.$(OBJEXT) \ - connection.$(OBJEXT) control.$(OBJEXT) dropin.$(OBJEXT) \ - dummy_device.$(OBJEXT) edge.$(OBJEXT) event.$(OBJEXT) \ - graph.$(OBJEXT) hash.$(OBJEXT) list.$(OBJEXT) logger.$(OBJEXT) \ - meta.$(OBJEXT) multicast_device.$(OBJEXT) names.$(OBJEXT) \ - net.$(OBJEXT) net_packet.$(OBJEXT) net_setup.$(OBJEXT) \ - net_socket.$(OBJEXT) netutl.$(OBJEXT) node.$(OBJEXT) \ - process.$(OBJEXT) protocol.$(OBJEXT) protocol_auth.$(OBJEXT) \ +am_tincd_OBJECTS = autoconnect.$(OBJEXT) buffer.$(OBJEXT) \ + conf.$(OBJEXT) connection.$(OBJEXT) control.$(OBJEXT) \ + dropin.$(OBJEXT) dummy_device.$(OBJEXT) edge.$(OBJEXT) \ + event.$(OBJEXT) fd_device.$(OBJEXT) graph.$(OBJEXT) \ + hash.$(OBJEXT) list.$(OBJEXT) logger.$(OBJEXT) meta.$(OBJEXT) \ + multicast_device.$(OBJEXT) names.$(OBJEXT) net.$(OBJEXT) \ + net_packet.$(OBJEXT) net_setup.$(OBJEXT) net_socket.$(OBJEXT) \ + netutl.$(OBJEXT) node.$(OBJEXT) process.$(OBJEXT) \ + protocol.$(OBJEXT) protocol_auth.$(OBJEXT) \ protocol_edge.$(OBJEXT) protocol_key.$(OBJEXT) \ protocol_misc.$(OBJEXT) protocol_subnet.$(OBJEXT) \ raw_socket_device.$(OBJEXT) route.$(OBJEXT) script.$(OBJEXT) \ @@ -570,7 +571,6 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ CLEANFILES = version_git.h ed25519_SOURCES = \ - ed25519/add_scalar.c \ ed25519/ed25519.h \ ed25519/fe.c ed25519/fe.h \ ed25519/fixedint.h \ @@ -588,16 +588,16 @@ chacha_poly1305_SOURCES = \ chacha-poly1305/chacha-poly1305.c chacha-poly1305/chacha-poly1305.h \ chacha-poly1305/poly1305.c chacha-poly1305/poly1305.h -tincd_SOURCES = buffer.c buffer.h cipher.h conf.c conf.h connection.c \ - connection.h control.c control.h control_common.h crypto.h \ - device.h digest.h dropin.c dropin.h dummy_device.c ecdh.h \ - ecdsa.h ecdsagen.h edge.c edge.h ethernet.h event.c event.h \ - graph.c graph.h hash.c hash.h have.h ipv4.h ipv6.h list.c \ - list.h logger.c logger.h meta.c meta.h multicast_device.c \ - names.c names.h net.c net.h net_packet.c net_setup.c \ - net_socket.c netutl.c netutl.h node.c node.h prf.h process.c \ - process.h protocol.c protocol.h protocol_auth.c \ - protocol_edge.c protocol_key.c protocol_misc.c \ +tincd_SOURCES = autoconnect.c autoconnect.h buffer.c buffer.h cipher.h \ + conf.c conf.h connection.c connection.h control.c control.h \ + control_common.h crypto.h device.h digest.h dropin.c dropin.h \ + dummy_device.c ecdh.h ecdsa.h ecdsagen.h edge.c edge.h \ + ethernet.h event.c event.h fd_device.c graph.c graph.h hash.c \ + hash.h have.h ipv4.h ipv6.h list.c list.h logger.c logger.h \ + meta.c meta.h multicast_device.c names.c names.h net.c net.h \ + net_packet.c net_setup.c net_socket.c netutl.c netutl.h node.c \ + node.h prf.h process.c process.h protocol.c protocol.h \ + protocol_auth.c protocol_edge.c protocol_key.c protocol_misc.c \ protocol_subnet.c raw_socket_device.c route.c route.h rsa.h \ rsagen.h script.c script.h splay_tree.c splay_tree.h sptps.c \ sptps.h subnet.c subnet.h subnet_parse.c system.h tincd.c \ @@ -666,6 +666,9 @@ $(top_srcdir)/configure: $(am__configure_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): + +clean-checkPROGRAMS: + -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS) install-sbinPROGRAMS: $(sbin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ @@ -732,8 +735,6 @@ ed25519/$(DEPDIR)/$(am__dirstamp): @: > ed25519/$(DEPDIR)/$(am__dirstamp) ed25519/ecdsagen.$(OBJEXT): ed25519/$(am__dirstamp) \ ed25519/$(DEPDIR)/$(am__dirstamp) -ed25519/add_scalar.$(OBJEXT): ed25519/$(am__dirstamp) \ - ed25519/$(DEPDIR)/$(am__dirstamp) ed25519/fe.$(OBJEXT): ed25519/$(am__dirstamp) \ ed25519/$(DEPDIR)/$(am__dirstamp) ed25519/ge.$(OBJEXT): ed25519/$(am__dirstamp) \ @@ -892,6 +893,7 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/autoconnect.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buffer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connection.Po@am__quote@ @@ -900,6 +902,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy_device.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)/fd_device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsck.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@ @@ -950,7 +953,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/chacha.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/poly1305.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@cygwin/$(DEPDIR)/device.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/add_scalar.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdh.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdsa.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdsagen.Po@am__quote@ @@ -1079,6 +1081,7 @@ distdir: $(DISTFILES) fi; \ done check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) check: check-am all-am: Makefile $(PROGRAMS) installdirs: @@ -1138,7 +1141,8 @@ maintainer-clean-generic: @echo "it deletes files that may require special tools to rebuild." clean: clean-am -clean-am: clean-generic clean-sbinPROGRAMS mostlyclean-am +clean-am: clean-checkPROGRAMS clean-generic clean-sbinPROGRAMS \ + mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) bsd/$(DEPDIR) chacha-poly1305/$(DEPDIR) cygwin/$(DEPDIR) ed25519/$(DEPDIR) gcrypt/$(DEPDIR) linux/$(DEPDIR) mingw/$(DEPDIR) nolegacy/$(DEPDIR) openssl/$(DEPDIR) solaris/$(DEPDIR) @@ -1205,21 +1209,22 @@ ps-am: uninstall-am: uninstall-sbinPROGRAMS -.MAKE: install-am install-strip +.MAKE: check-am install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ - clean-sbinPROGRAMS cscopelist-am ctags ctags-am distclean \ - distclean-compile distclean-generic distclean-tags distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am install-man install-pdf \ - install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \ - install-strip installcheck installcheck-am \ - installcheck-sbinPROGRAMS installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ - uninstall-am uninstall-sbinPROGRAMS +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ + clean-checkPROGRAMS clean-generic clean-sbinPROGRAMS \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-sbinPROGRAMS install-strip \ + installcheck installcheck-am installcheck-sbinPROGRAMS \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am \ + uninstall-sbinPROGRAMS .PRECIOUS: Makefile diff --git a/src/autoconnect.c b/src/autoconnect.c new file mode 100644 index 0000000..1ea51b5 --- /dev/null +++ b/src/autoconnect.c @@ -0,0 +1,174 @@ +/* + autoconnect.c -- automatic connection establishment + Copyright (C) 2017 Guus Sliepen + + 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 "connection.h" +#include "logger.h" +#include "node.h" +#include "xalloc.h" + +static void make_new_connection() { + /* Select a random node we haven't connected to yet. */ + int count = 0; + for splay_each(node_t, n, node_tree) { + if(n == myself || n->connection || !(n->status.has_address || n->status.reachable)) + continue; + count++; + } + + if(!count) + return; + + int r = rand() % count; + + for splay_each(node_t, n, node_tree) { + if(n == myself || n->connection || !(n->status.has_address || n->status.reachable)) + continue; + + if(r--) + continue; + + 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 = xzalloc(sizeof *outgoing); + outgoing->name = xstrdup(n->name); + list_insert_tail(outgoing_list, outgoing); + setup_outgoing_connection(outgoing); + } + + break; + } +} + +static void connect_to_unreachable() { + /* Select a random known node. The rationale is that if there are many + * reachable nodes, and only a few unreachable nodes, we don't want all + * reachable nodes to try to connect to the unreachable ones at the + * same time. This way, we back off automatically. Conversely, if there + * are only a few reachable nodes, and many unreachable ones, we're + * going to try harder to connect to them. */ + + int r = rand() % node_tree->count; + + for splay_each(node_t, n, node_tree) { + if(r--) + continue; + + /* Is it unreachable and do we know an address for it? If not, return. */ + if(n == myself || n->connection || n->status.reachable || !n->status.has_address) + return; + + /* Are we already trying to make an outgoing connection to it? If not, return. */ + for list_each(outgoing_t, outgoing, outgoing_list) + if(!strcmp(outgoing->name, n->name)) + return; + + logger(DEBUG_CONNECTIONS, LOG_INFO, "Autoconnecting to %s", n->name); + outgoing_t *outgoing = xzalloc(sizeof *outgoing); + outgoing->name = xstrdup(n->name); + list_insert_tail(outgoing_list, outgoing); + setup_outgoing_connection(outgoing); + + return; + } +} + +static void drop_superfluous_outgoing_connection() { + /* Choose a random outgoing connection to a node that has at least one other connection. */ + int count = 0; + for list_each(connection_t, c, connection_list) { + if(!c->edge || !c->outgoing || !c->node || c->node->edge_tree->count < 2) + continue; + count++; + } + + if(!count) + return; + + int r = rand() % count; + + for list_each(connection_t, c, connection_list) { + if(!c->edge || !c->outgoing || !c->node || c->node->edge_tree->count < 2) + continue; + + if(r--) + continue; + + logger(DEBUG_CONNECTIONS, LOG_INFO, "Autodisconnecting from %s", c->name); + list_delete(outgoing_list, c->outgoing); + c->outgoing = NULL; + terminate_connection(c, c->edge); + break; + } +} + +static void drop_superfluous_pending_connections() { + for list_each(outgoing_t, o, outgoing_list) { + /* Only look for connections that are waiting to be retried later. */ + bool found = false; + for list_each(connection_t, c, connection_list) { + if(c->outgoing == o) { + found = true; + break; + } + } + + if(found) + continue; + + logger(DEBUG_CONNECTIONS, LOG_INFO, "Cancelled outgoing connection to %s", o->name); + list_delete_node(outgoing_list, node); + } +} + +void do_autoconnect() { + /* Count number of active connections. */ + int nc = 0; + for list_each(connection_t, c, connection_list) { + if(c->edge) + nc++; + } + + /* Less than 3 connections? Eagerly try to make a new one. */ + if(nc < 3) { + make_new_connection(); + return; + } + + /* More than 3 connections? See if we can get rid of a superfluous one. */ + if(nc > 3) + drop_superfluous_outgoing_connection(); + + + /* Check if there are unreachable nodes that we should try to connect to. */ + connect_to_unreachable(); + + /* Drop pending outgoing connections from the outgoing list. */ + drop_superfluous_pending_connections(); +} diff --git a/src/autoconnect.h b/src/autoconnect.h new file mode 100644 index 0000000..dc3ee1c --- /dev/null +++ b/src/autoconnect.h @@ -0,0 +1,25 @@ +/* + autoconnect.h -- header for autoconnect.c + Copyright (C) 2017 Guus Sliepen + + 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_AUTOCONNECT_H__ +#define __TINC_AUTOCONNECT_H__ + +extern void do_autoconnect(void); + +#endif diff --git a/src/bsd/device.c b/src/bsd/device.c index 5428262..4a63e84 100644 --- a/src/bsd/device.c +++ b/src/bsd/device.c @@ -1,7 +1,7 @@ /* device.c -- Interaction BSD tun/tap device Copyright (C) 2001-2005 Ivo Timmermans, - 2001-2016 Guus Sliepen + 2001-2017 Guus Sliepen 2009 Grzegorz Dymarek This program is free software; you can redistribute it and/or modify @@ -198,18 +198,19 @@ static bool setup_device(void) { // Guess what the corresponding interface is called - char *realname; + char *realname = NULL; #if defined(HAVE_FDEVNAME) - realname = fdevname(device_fd) ? : device; + realname = fdevname(device_fd); #elif defined(HAVE_DEVNAME) struct stat buf; if(!fstat(device_fd, &buf)) - realname = devname(buf.st_rdev, S_IFCHR) ? : device; -#else - realname = device; + realname = devname(buf.st_rdev, S_IFCHR); #endif + if(!realname) + realname = device; + if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) iface = xstrdup(strrchr(realname, '/') ? strrchr(realname, '/') + 1 : realname); else if(strcmp(iface, strrchr(realname, '/') ? strrchr(realname, '/') + 1 : realname)) diff --git a/src/cipher.h b/src/cipher.h index 3f98c18..44db40f 100644 --- a/src/cipher.h +++ b/src/cipher.h @@ -1,6 +1,6 @@ /* cipher.h -- header file cipher.c - Copyright (C) 2007-2013 Guus Sliepen + Copyright (C) 2007-2016 Guus Sliepen 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 @@ -30,10 +30,10 @@ typedef struct cipher cipher_t; extern cipher_t *cipher_open_by_name(const char *) __attribute__ ((__malloc__)); extern cipher_t *cipher_open_by_nid(int) __attribute__ ((__malloc__)); -extern cipher_t *cipher_open_blowfish_ofb(void) __attribute__ ((__malloc__)); extern void cipher_close(cipher_t *); extern size_t cipher_keylength(const cipher_t *); extern size_t cipher_blocksize(const cipher_t *); +extern uint64_t cipher_budget(const cipher_t *); extern void cipher_get_key(const cipher_t *, void *); extern bool cipher_set_key(cipher_t *, void *, bool) __attribute__ ((__warn_unused_result__)); extern bool cipher_set_key_from_rsa(cipher_t *, void *, size_t, bool) __attribute__ ((__warn_unused_result__)); diff --git a/src/connection.h b/src/connection.h index 7fa769f..acd77bc 100644 --- a/src/connection.h +++ b/src/connection.h @@ -81,6 +81,8 @@ typedef struct connection_t { cipher_t *outcipher; /* Cipher we will use to send data to him */ digest_t *indigest; digest_t *outdigest; + uint64_t inbudget; + uint64_t outbudget; #endif ecdsa_t *ecdsa; /* his public ECDSA key */ diff --git a/src/device.h b/src/device.h index 8046a25..fa27df3 100644 --- a/src/device.h +++ b/src/device.h @@ -40,6 +40,7 @@ extern const devops_t os_devops; extern const devops_t dummy_devops; extern const devops_t raw_socket_devops; extern const devops_t multicast_devops; +extern const devops_t fd_devops; extern const devops_t uml_devops; extern const devops_t vde_devops; extern devops_t devops; diff --git a/src/digest.h b/src/digest.h index 204048a..a3691bf 100644 --- a/src/digest.h +++ b/src/digest.h @@ -1,6 +1,6 @@ /* digest.h -- header file digest.c - Copyright (C) 2007-2013 Guus Sliepen + Copyright (C) 2007-2016 Guus Sliepen 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 @@ -28,7 +28,6 @@ typedef struct digest digest_t; extern digest_t *digest_open_by_name(const char *name, int maclength) __attribute__ ((__malloc__)); extern digest_t *digest_open_by_nid(int nid, int maclength) __attribute__ ((__malloc__)); -extern digest_t *digest_open_sha1(int maclength) __attribute__ ((__malloc__)); extern void digest_close(digest_t *); extern bool digest_create(digest_t *, const void *indata, size_t inlen, void *outdata) __attribute__ ((__warn_unused_result__)); extern bool digest_verify(digest_t *, const void *indata, size_t inlen, const void *digestdata) __attribute__ ((__warn_unused_result__)); diff --git a/src/dropin.c b/src/dropin.c index c7b558a..a4f7a65 100644 --- a/src/dropin.c +++ b/src/dropin.c @@ -106,14 +106,13 @@ int vasprintf(char **buf, const char *fmt, va_list ap) { va_copy(aq, ap); status = vsnprintf(*buf, len, fmt, aq); - buf[len - 1] = 0; va_end(aq); if(status >= 0) *buf = xrealloc(*buf, status + 1); if(status > len - 1) { - len = status; + len = status + 1; va_copy(aq, ap); status = vsnprintf(*buf, len, fmt, aq); va_end(aq); diff --git a/src/ed25519/add_scalar.c b/src/ed25519/add_scalar.c deleted file mode 100644 index 262ec72..0000000 --- a/src/ed25519/add_scalar.c +++ /dev/null @@ -1,56 +0,0 @@ -#include "ed25519.h" -#include "ge.h" -#include "sc.h" - - -/* see http://crypto.stackexchange.com/a/6215/4697 */ -void ed25519_add_scalar(unsigned char *public_key, unsigned char *private_key, const unsigned char *scalar) { - const unsigned char SC_1[32] = {1}; /* scalar with value 1 */ - - unsigned char n[32]; - ge_p3 nB; - ge_p1p1 A_p1p1; - ge_p3 A; - ge_p3 public_key_unpacked; - ge_cached T; - - int i; - - /* copy the scalar and clear highest bit */ - for (i = 0; i < 31; ++i) { - n[i] = scalar[i]; - } - n[31] = scalar[31] & 127; - - /* private key: a = n + t */ - if (private_key) { - sc_muladd(private_key, SC_1, n, private_key); - } - - /* public key: A = nB + T */ - if (public_key) { - /* if we know the private key we don't need a point addition, which is faster */ - /* using a "timing attack" you could find out wether or not we know the private - key, but this information seems rather useless - if this is important pass - public_key and private_key seperately in 2 function calls */ - if (private_key) { - ge_scalarmult_base(&A, private_key); - } else { - /* unpack public key into T */ - ge_frombytes_negate_vartime(&public_key_unpacked, public_key); - fe_neg(public_key_unpacked.X, public_key_unpacked.X); // undo negate - fe_neg(public_key_unpacked.T, public_key_unpacked.T); // undo negate - ge_p3_to_cached(&T, &public_key_unpacked); - - /* calculate n*B */ - ge_scalarmult_base(&nB, n); - - /* A = n*B + T */ - ge_add(&A_p1p1, &nB, &T); - ge_p1p1_to_p3(&A, &A_p1p1); - } - - /* pack public key */ - ge_p3_tobytes(public_key, &A); - } -} diff --git a/src/ed25519/ed25519.h b/src/ed25519/ed25519.h index bb34f89..5cb82d5 100644 --- a/src/ed25519/ed25519.h +++ b/src/ed25519/ed25519.h @@ -27,7 +27,6 @@ int ED25519_DECLSPEC ed25519_create_seed(unsigned char *seed); void ED25519_DECLSPEC ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, const unsigned char *seed); void ED25519_DECLSPEC ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key, const unsigned char *private_key); int ED25519_DECLSPEC ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *private_key); -void ED25519_DECLSPEC ed25519_add_scalar(unsigned char *public_key, unsigned char *private_key, const unsigned char *scalar); void ED25519_DECLSPEC ed25519_key_exchange(unsigned char *shared_secret, const unsigned char *public_key, const unsigned char *private_key); diff --git a/src/ed25519/sc.c b/src/ed25519/sc.c index 42cfc2d..3364de4 100644 --- a/src/ed25519/sc.c +++ b/src/ed25519/sc.c @@ -81,42 +81,36 @@ void sc_reduce(unsigned char *s) { s14 -= s23 * 997805; s15 += s23 * 136657; s16 -= s23 * 683901; - s23 = 0; s10 += s22 * 666643; s11 += s22 * 470296; s12 += s22 * 654183; s13 -= s22 * 997805; s14 += s22 * 136657; s15 -= s22 * 683901; - s22 = 0; s9 += s21 * 666643; s10 += s21 * 470296; s11 += s21 * 654183; s12 -= s21 * 997805; s13 += s21 * 136657; s14 -= s21 * 683901; - s21 = 0; s8 += s20 * 666643; s9 += s20 * 470296; s10 += s20 * 654183; s11 -= s20 * 997805; s12 += s20 * 136657; s13 -= s20 * 683901; - s20 = 0; s7 += s19 * 666643; s8 += s19 * 470296; s9 += s19 * 654183; s10 -= s19 * 997805; s11 += s19 * 136657; s12 -= s19 * 683901; - s19 = 0; s6 += s18 * 666643; s7 += s18 * 470296; s8 += s18 * 654183; s9 -= s18 * 997805; s10 += s18 * 136657; s11 -= s18 * 683901; - s18 = 0; carry6 = (s6 + (1 << 20)) >> 21; s7 += carry6; s6 -= shl64(carry6, 21); @@ -156,35 +150,30 @@ void sc_reduce(unsigned char *s) { s8 -= s17 * 997805; s9 += s17 * 136657; s10 -= s17 * 683901; - s17 = 0; s4 += s16 * 666643; s5 += s16 * 470296; s6 += s16 * 654183; s7 -= s16 * 997805; s8 += s16 * 136657; s9 -= s16 * 683901; - s16 = 0; s3 += s15 * 666643; s4 += s15 * 470296; s5 += s15 * 654183; s6 -= s15 * 997805; s7 += s15 * 136657; s8 -= s15 * 683901; - s15 = 0; s2 += s14 * 666643; s3 += s14 * 470296; s4 += s14 * 654183; s5 -= s14 * 997805; s6 += s14 * 136657; s7 -= s14 * 683901; - s14 = 0; s1 += s13 * 666643; s2 += s13 * 470296; s3 += s13 * 654183; s4 -= s13 * 997805; s5 += s13 * 136657; s6 -= s13 * 683901; - s13 = 0; s0 += s12 * 666643; s1 += s12 * 470296; s2 += s12 * 654183; @@ -277,7 +266,6 @@ void sc_reduce(unsigned char *s) { s3 -= s12 * 997805; s4 += s12 * 136657; s5 -= s12 * 683901; - s12 = 0; carry0 = s0 >> 21; s1 += carry0; s0 -= shl64(carry0, 21); @@ -543,42 +531,36 @@ void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, s14 -= s23 * 997805; s15 += s23 * 136657; s16 -= s23 * 683901; - s23 = 0; s10 += s22 * 666643; s11 += s22 * 470296; s12 += s22 * 654183; s13 -= s22 * 997805; s14 += s22 * 136657; s15 -= s22 * 683901; - s22 = 0; s9 += s21 * 666643; s10 += s21 * 470296; s11 += s21 * 654183; s12 -= s21 * 997805; s13 += s21 * 136657; s14 -= s21 * 683901; - s21 = 0; s8 += s20 * 666643; s9 += s20 * 470296; s10 += s20 * 654183; s11 -= s20 * 997805; s12 += s20 * 136657; s13 -= s20 * 683901; - s20 = 0; s7 += s19 * 666643; s8 += s19 * 470296; s9 += s19 * 654183; s10 -= s19 * 997805; s11 += s19 * 136657; s12 -= s19 * 683901; - s19 = 0; s6 += s18 * 666643; s7 += s18 * 470296; s8 += s18 * 654183; s9 -= s18 * 997805; s10 += s18 * 136657; s11 -= s18 * 683901; - s18 = 0; carry6 = (s6 + (1 << 20)) >> 21; s7 += carry6; s6 -= shl64(carry6, 21); @@ -618,35 +600,30 @@ void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, s8 -= s17 * 997805; s9 += s17 * 136657; s10 -= s17 * 683901; - s17 = 0; s4 += s16 * 666643; s5 += s16 * 470296; s6 += s16 * 654183; s7 -= s16 * 997805; s8 += s16 * 136657; s9 -= s16 * 683901; - s16 = 0; s3 += s15 * 666643; s4 += s15 * 470296; s5 += s15 * 654183; s6 -= s15 * 997805; s7 += s15 * 136657; s8 -= s15 * 683901; - s15 = 0; s2 += s14 * 666643; s3 += s14 * 470296; s4 += s14 * 654183; s5 -= s14 * 997805; s6 += s14 * 136657; s7 -= s14 * 683901; - s14 = 0; s1 += s13 * 666643; s2 += s13 * 470296; s3 += s13 * 654183; s4 -= s13 * 997805; s5 += s13 * 136657; s6 -= s13 * 683901; - s13 = 0; s0 += s12 * 666643; s1 += s12 * 470296; s2 += s12 * 654183; @@ -739,7 +716,6 @@ void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, s3 -= s12 * 997805; s4 += s12 * 136657; s5 -= s12 * 683901; - s12 = 0; carry0 = s0 >> 21; s1 += carry0; s0 -= shl64(carry0, 21); diff --git a/src/ethernet.h b/src/ethernet.h index 085e96a..0b4a1db 100644 --- a/src/ethernet.h +++ b/src/ethernet.h @@ -25,6 +25,15 @@ #define ETH_ALEN 6 #endif +#ifndef ETH_HLEN +#define ETH_HLEN 14 +#endif + +#ifndef ETHER_TYPE_LEN +#define ETHER_TYPE_LEN 2 +#endif + + #ifndef ARPHRD_ETHER #define ARPHRD_ETHER 1 #endif @@ -45,6 +54,10 @@ #define ETH_P_8021Q 0x8100 #endif +#ifndef ETH_P_MAX +#define ETH_P_MAX 0xFFFF +#endif + #ifndef HAVE_STRUCT_ETHER_HEADER struct ether_header { uint8_t ether_dhost[ETH_ALEN]; diff --git a/src/event.c b/src/event.c index 59b96e3..858e1d9 100644 --- a/src/event.c +++ b/src/event.c @@ -357,10 +357,13 @@ bool event_loop(void) { WSANETWORKEVENTS network_events; if (WSAEnumNetworkEvents(io->fd, io->event, &network_events) != 0) return false; - if (network_events.lNetworkEvents & WRITE_EVENTS) - io->cb(io->data, IO_WRITE); if (network_events.lNetworkEvents & READ_EVENTS) io->cb(io->data, IO_READ); + /* + The fd might be available for write too. However, if we already fired the read callback, that + callback might have deleted the io (e.g. through terminate_connection()), so we can't fire the + write callback here. Instead, we loop back and let the writable io loop above handle it. + */ } } #endif diff --git a/src/fd_device.c b/src/fd_device.c new file mode 100644 index 0000000..67e0cb7 --- /dev/null +++ b/src/fd_device.c @@ -0,0 +1,123 @@ +/* + fd_device.c -- Interaction with Android tun fd + Copyright (C) 2001-2005 Ivo Timmermans, + 2001-2016 Guus Sliepen + 2009 Grzegorz Dymarek + 2016 Pacien TRAN-GIRARD + + 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 "conf.h" +#include "device.h" +#include "ethernet.h" +#include "logger.h" +#include "net.h" +#include "route.h" +#include "utils.h" + +static inline bool check_config(void) { + if(routing_mode == RMODE_SWITCH) { + logger(DEBUG_ALWAYS, LOG_ERR, "Switch mode not supported (requires unsupported TAP device)!"); + return false; + } + + if(!get_config_int(lookup_config(config_tree, "Device"), &device_fd)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not read fd from configuration!"); + return false; + } + + return true; +} + +static bool setup_device(void) { + if(!check_config()) { + return false; + } + + if(device_fd < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s!", device, strerror(errno)); + return false; + } + + logger(DEBUG_ALWAYS, LOG_INFO, "fd/%d adapter set up.", device_fd); + + return true; +} + +static void close_device(void) { + close(device_fd); + device_fd = -1; +} + +static inline uint16_t get_ip_ethertype(vpn_packet_t *packet) { + switch (DATA(packet)[ETH_HLEN] >> 4) { + case 4: + return ETH_P_IP; + + case 6: + return ETH_P_IPV6; + + default: + return ETH_P_MAX; + } +} + +static inline void set_etherheader(vpn_packet_t *packet, uint16_t ethertype) { + memset(DATA(packet), 0, ETH_HLEN - ETHER_TYPE_LEN); + + DATA(packet)[ETH_HLEN - ETHER_TYPE_LEN] = (ethertype >> 8) & 0xFF; + DATA(packet)[ETH_HLEN - ETHER_TYPE_LEN + 1] = ethertype & 0xFF; +} + +static bool read_packet(vpn_packet_t *packet) { + int lenin = read(device_fd, DATA(packet) + ETH_HLEN, MTU - ETH_HLEN); + if(lenin <= 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from fd/%d: %s!", device_fd, strerror(errno)); + return false; + } + + uint16_t ethertype = get_ip_ethertype(packet); + if(ethertype == ETH_P_MAX) { + logger(DEBUG_TRAFFIC, LOG_ERR, "Unknown IP version while reading packet from fd/%d!", device_fd); + return false; + } + + set_etherheader(packet, ethertype); + packet->len = lenin + ETH_HLEN; + + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from fd/%d.", packet->len, device_fd); + + return true; +} + +static bool write_packet(vpn_packet_t *packet) { + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to fd/%d.", packet->len, device_fd); + + if(write(device_fd, DATA(packet) + ETH_HLEN, packet->len - ETH_HLEN) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to fd/%d: %s!", device_fd, strerror(errno)); + return false; + } + + return true; +} + +const devops_t fd_devops = { + .setup = setup_device, + .close = close_device, + .read = read_packet, + .write = write_packet, +}; diff --git a/src/fsck.c b/src/fsck.c index b90710b..e5e7dd5 100644 --- a/src/fsck.c +++ b/src/fsck.c @@ -297,9 +297,10 @@ int fsck(const char *argv0) { rsa_t *rsa_pub = NULL; f = fopen(fname, "r"); - if(f) + if(f) { rsa_pub = rsa_read_pem_public_key(f); - fclose(f); + fclose(f); + } if(rsa_priv) { if(!rsa_pub) { @@ -352,12 +353,12 @@ int fsck(const char *argv0) { f = fopen(fname, "r"); if(f) { ecdsa_pub = get_pubkey(f); - if(!f) { + if(!ecdsa_pub) { rewind(f); ecdsa_pub = ecdsa_read_pem_public_key(f); } + fclose(f); } - fclose(f); if(ecdsa_priv) { if(!ecdsa_pub) { diff --git a/src/graph.c b/src/graph.c index e570feb..1f1fdb3 100644 --- a/src/graph.c +++ b/src/graph.c @@ -1,6 +1,6 @@ /* graph.c -- graph algorithms - Copyright (C) 2001-2013 Guus Sliepen , + Copyright (C) 2001-2017 Guus Sliepen , 2001-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -247,28 +247,23 @@ static void check_reachability(void) { char *name; char *address; char *port; - char *envp[8] = {NULL}; - xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); - xasprintf(&envp[1], "DEVICE=%s", device ? : ""); - xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); - xasprintf(&envp[3], "NODE=%s", n->name); + environment_t env; + environment_init(&env); + environment_add(&env, "NODE=%s", n->name); sockaddr2str(&n->address, &address, &port); - xasprintf(&envp[4], "REMOTEADDRESS=%s", address); - xasprintf(&envp[5], "REMOTEPORT=%s", port); - xasprintf(&envp[6], "NAME=%s", myself->name); + environment_add(&env, "REMOTEADDRESS=%s", address); + environment_add(&env, "REMOTEPORT=%s", port); - execute_script(n->status.reachable ? "host-up" : "host-down", envp); + execute_script(n->status.reachable ? "host-up" : "host-down", &env); xasprintf(&name, n->status.reachable ? "hosts/%s-up" : "hosts/%s-down", n->name); - execute_script(name, envp); + execute_script(name, &env); free(name); free(address); free(port); - - for(int i = 0; i < 7; i++) - free(envp[i]); + environment_exit(&env); subnet_update(n, NULL, n->status.reachable); diff --git a/src/ifconfig.c b/src/ifconfig.c index 7688a3c..0b99402 100644 --- a/src/ifconfig.c +++ b/src/ifconfig.c @@ -1,6 +1,6 @@ /* ifconfig.c -- Generate platform specific interface configuration commands - Copyright (C) 2016 Guus Sliepen + Copyright (C) 2016-2017 Guus Sliepen 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 @@ -104,13 +104,6 @@ void ifconfig_address(FILE *out, const char *value) { case SUBNET_IPV6: fprintf(out, "ip addr replace %s dev \"$INTERFACE\"\n", address_str); break; default: return; } -#elif defined(HAVE_BSD) - switch(address.type) { - case SUBNET_MAC: fprintf(out, "ifconfig \"$INTERFACE\" link %s\n", address_str); break; - case SUBNET_IPV4: fprintf(out, "ifconfig \"$INTERFACE\" %s\n", address_str); break; - case SUBNET_IPV6: fprintf(out, "ifconfig \"$INTERFACE\" inet6 %s\n", address_str); break; - default: return; - } #elif defined(HAVE_MINGW) || defined(HAVE_CYGWIN) switch(address.type) { case SUBNET_MAC: fprintf(out, "ip link set \"$INTERFACE\" address %s\n", address_str); break; @@ -118,6 +111,13 @@ void ifconfig_address(FILE *out, const char *value) { case SUBNET_IPV6: fprintf(out, "netsh inetface ipv6 set address \"$INTERFACE\" static %s\n", address_str); break; default: return; } +#else // assume BSD + switch(address.type) { + case SUBNET_MAC: fprintf(out, "ifconfig \"$INTERFACE\" link %s\n", address_str); break; + case SUBNET_IPV4: fprintf(out, "ifconfig \"$INTERFACE\" %s\n", address_str); break; + case SUBNET_IPV6: fprintf(out, "ifconfig \"$INTERFACE\" inet6 %s\n", address_str); break; + default: return; + } #endif } @@ -152,8 +152,21 @@ void ifconfig_route(FILE *out, const char *value) { default: return; } } -#elif defined(HAVE_BSD) - // BSD route command is silly and doesn't accept an interface name as a destination. +#elif defined(HAVE_MINGW) || defined(HAVE_CYGWIN) + if(*gateway_str) { + switch(subnet.type) { + case SUBNET_IPV4: fprintf(out, "netsh inetface ipv4 add route %s \"%%INTERFACE%%\" %s\n", subnet_str, gateway_str); break; + case SUBNET_IPV6: fprintf(out, "netsh inetface ipv6 add route %s \"%%INTERFACE%%\" %s\n", subnet_str, gateway_str); break; + default: return; + } + } else { + switch(subnet.type) { + case SUBNET_IPV4: fprintf(out, "netsh inetface ipv4 add route %s \"%%INTERFACE%%\"\n", subnet_str); break; + case SUBNET_IPV6: fprintf(out, "netsh inetface ipv6 add route %s \"%%INTERFACE%%\"\n", subnet_str); break; + default: return; + } + } +#else // assume BSD if(!*gateway_str) { switch(subnet.type) { case SUBNET_IPV4: @@ -180,19 +193,5 @@ void ifconfig_route(FILE *out, const char *value) { case SUBNET_IPV6: fprintf(out, "route add -inet6 %s %s\n", subnet_str, gateway_str); break; default: return; } -#elif defined(HAVE_MINGW) || defined(HAVE_CYGWIN) - if(*gateway_str) { - switch(subnet.type) { - case SUBNET_IPV4: fprintf(out, "netsh inetface ipv4 add route %s \"%%INTERFACE%%\" %s\n", subnet_str, gateway_str); break; - case SUBNET_IPV6: fprintf(out, "netsh inetface ipv6 add route %s \"%%INTERFACE%%\" %s\n", subnet_str, gateway_str); break; - default: return; - } - } else { - switch(subnet.type) { - case SUBNET_IPV4: fprintf(out, "netsh inetface ipv4 add route %s \"%%INTERFACE%%\"\n", subnet_str); break; - case SUBNET_IPV6: fprintf(out, "netsh inetface ipv6 add route %s \"%%INTERFACE%%\"\n", subnet_str); break; - default: return; - } - } #endif } diff --git a/src/info.c b/src/info.c index b9a6fcf..2a6934b 100644 --- a/src/info.c +++ b/src/info.c @@ -1,6 +1,6 @@ /* info.c -- Show information about a node, subnet or address - Copyright (C) 2012-2013 Guus Sliepen + Copyright (C) 2012-2017 Guus Sliepen 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 @@ -69,7 +69,7 @@ static int info_node(int fd, const char *item) { long int last_state_change; while(recvline(fd, line, sizeof line)) { - int n = sscanf(line, "%d %d %s %s %s port %s %d %d %d %d %x %"PRIx32" %s %s %d %hd %hd %hd %ld", &code, &req, node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_union.raw, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change); + int n = sscanf(line, "%d %d %4095s %4095s %4095s port %4095s %d %d %d %d %x %"PRIx32" %4095s %4095s %d %hd %hd %hd %ld", &code, &req, node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_union.raw, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change); if(n == 2) break; @@ -91,7 +91,7 @@ static int info_node(int fd, const char *item) { } while(recvline(fd, line, sizeof line)) { - if(sscanf(line, "%d %d %s", &code, &req, node) == 2) + if(sscanf(line, "%d %d %4095s", &code, &req, node) == 2) break; } @@ -158,7 +158,7 @@ static int info_node(int fd, const char *item) { printf("Edges: "); sendline(fd, "%d %d %s", CONTROL, REQ_DUMP_EDGES, item); while(recvline(fd, line, sizeof line)) { - int n = sscanf(line, "%d %d %s %s", &code, &req, from, to); + int n = sscanf(line, "%d %d %4095s %4095s", &code, &req, from, to); if(n == 2) break; if(n != 4) { @@ -174,7 +174,7 @@ static int info_node(int fd, const char *item) { printf("Subnets: "); sendline(fd, "%d %d %s", CONTROL, REQ_DUMP_SUBNETS, item); while(recvline(fd, line, sizeof line)) { - int n = sscanf(line, "%d %d %s %s", &code, &req, subnet, from); + int n = sscanf(line, "%d %d %4095s %4095s", &code, &req, subnet, from); if(n == 2) break; if(n != 4) { @@ -209,7 +209,7 @@ static int info_subnet(int fd, const char *item) { sendline(fd, "%d %d %s", CONTROL, REQ_DUMP_SUBNETS, item); while(recvline(fd, line, sizeof line)) { - int n = sscanf(line, "%d %d %s %s", &code, &req, netstr, owner); + int n = sscanf(line, "%d %d %4095s %4095s", &code, &req, netstr, owner); if(n == 2) break; diff --git a/src/invitation.c b/src/invitation.c index 08afe78..0dfd9ea 100644 --- a/src/invitation.c +++ b/src/invitation.c @@ -1,6 +1,6 @@ /* invitation.c -- Create and accept invitations - Copyright (C) 2013-2015 Guus Sliepen + Copyright (C) 2013-2017 Guus Sliepen 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 @@ -239,7 +239,7 @@ int cmd_invite(int argc, char *argv[]) { return 1; } - char *myname = get_my_name(true); + myname = get_my_name(true); if(!myname) return 1; @@ -252,14 +252,14 @@ int cmd_invite(int argc, char *argv[]) { } // If a daemon is running, ensure no other nodes know about this name - bool found = false; if(connect_tincd(false)) { + bool found = false; sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES); while(recvline(fd, line, sizeof line)) { char node[4096]; int code, req; - if(sscanf(line, "%d %d %s", &code, &req, node) != 3) + if(sscanf(line, "%d %d %4095s", &code, &req, node) != 3) break; if(!strcmp(node, argv[1])) found = true; @@ -425,15 +425,13 @@ int cmd_invite(int argc, char *argv[]) { xasprintf(&url, "%s/%s%s", address, hash, cookie); // Call the inviation-created script - char *envp[6] = {}; - xasprintf(&envp[0], "NAME=%s", myname); - xasprintf(&envp[1], "NETNAME=%s", netname); - xasprintf(&envp[2], "NODE=%s", argv[1]); - xasprintf(&envp[3], "INVITATION_FILE=%s", filename); - xasprintf(&envp[4], "INVITATION_URL=%s", url); - execute_script("invitation-created", envp); - for(int i = 0; i < 6 && envp[i]; i++) - free(envp[i]); + environment_t env; + environment_init(&env); + environment_add(&env, "NODE=%s", argv[1]); + environment_add(&env, "INVITATION_FILE=%s", filename); + environment_add(&env, "INVITATION_URL=%s", url); + execute_script("invitation-created", &env); + environment_exit(&env); puts(url); free(url); @@ -609,6 +607,17 @@ make_names: return false; } + snprintf(filename, sizeof filename, "%s" SLASH "invitation-data", confbase); + FILE *finv = fopen(filename, "w"); + if(!finv || fwrite(data, datalen, 1, finv) != 1) { + fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno)); + fclose(fh); + fclose(f); + fclose(finv); + return false; + } + fclose(finv); + snprintf(filename, sizeof filename, "%s" SLASH "tinc-up.invitation", confbase); FILE *fup = fopen(filename, "w"); if(!fup) { @@ -688,7 +697,7 @@ make_names: } // Copy the safe variable to the right config file - fprintf(variables[i].type & VAR_HOST ? fh : f, "%s = %s\n", l, value); + fprintf((variables[i].type & VAR_HOST) ? fh : f, "%s = %s\n", l, value); } fclose(f); @@ -1046,7 +1055,7 @@ next: char hisname[4096] = ""; int code, hismajor, hisminor = 0; - if(!recvline(sock, line, sizeof line) || sscanf(line, "%d %s %d.%d", &code, hisname, &hismajor, &hisminor) < 3 || code != 0 || hismajor != PROT_MAJOR || !check_id(hisname) || !recvline(sock, line, sizeof line) || !rstrip(line) || sscanf(line, "%d ", &code) != 1 || code != ACK || strlen(line) < 3) { + if(!recvline(sock, line, sizeof line) || sscanf(line, "%d %4095s %d.%d", &code, hisname, &hismajor, &hisminor) < 3 || code != 0 || hismajor != PROT_MAJOR || !check_id(hisname) || !recvline(sock, line, sizeof line) || !rstrip(line) || sscanf(line, "%d ", &code) != 1 || code != ACK || strlen(line) < 3) { fprintf(stderr, "Cannot read greeting from peer\n"); closesocket(sock); goto next; diff --git a/src/linux/device.c b/src/linux/device.c index a06e6da..e273bfa 100644 --- a/src/linux/device.c +++ b/src/linux/device.c @@ -139,6 +139,9 @@ static bool read_packet(vpn_packet_t *packet) { if(inlen <= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); + if (errno == EBADFD) { /* File descriptor in bad state */ + event_exit(); + } return false; } diff --git a/src/logger.c b/src/logger.c index 6028e3d..4075ea8 100644 --- a/src/logger.c +++ b/src/logger.c @@ -1,6 +1,6 @@ /* logger.c -- logging code - Copyright (C) 2004-2015 Guus Sliepen + Copyright (C) 2004-2017 Guus Sliepen 2004-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -29,7 +29,7 @@ #include "process.h" #include "sptps.h" -debug_t debug_level = DEBUG_NOTHING; +int debug_level = DEBUG_NOTHING; static logmode_t logmode = LOGMODE_STDERR; static pid_t logpid; static FILE *logfile = NULL; diff --git a/src/logger.h b/src/logger.h index 252497b..f4f46f9 100644 --- a/src/logger.h +++ b/src/logger.h @@ -1,7 +1,7 @@ /* logger.h -- header file for logger.c Copyright (C) 1998-2005 Ivo Timmermans - 2000-2012 Guus Sliepen + 2000-2017 Guus Sliepen 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 @@ -67,7 +67,7 @@ enum { #include -extern debug_t debug_level; +extern int debug_level; extern bool logcontrol; extern int umbilical; extern void openlogger(const char *, logmode_t); diff --git a/src/meta.c b/src/meta.c index 260cb00..4b35798 100644 --- a/src/meta.c +++ b/src/meta.c @@ -65,6 +65,13 @@ bool send_meta(connection_t *c, const char *buffer, int length) { #ifdef DISABLE_LEGACY return false; #else + if(length > c->outbudget) { + logger(DEBUG_META, LOG_ERR, "Byte limit exceeded for encryption to %s (%s)", c->name, c->hostname); + return false; + } else { + c->outbudget -= length; + } + size_t outlen = length; if(!cipher_encrypt(c->outcipher, buffer, length, buffer_prepare(&c->outbuf, length), &outlen, false) || outlen != length) { @@ -220,6 +227,13 @@ bool receive_meta(connection_t *c) { #ifdef DISABLE_LEGACY return false; #else + if(inlen > c->inbudget) { + logger(DEBUG_META, LOG_ERR, "yte limit exceeded for decryption from %s (%s)", c->name, c->hostname); + return false; + } else { + c->inbudget -= inlen; + } + size_t outlen = inlen; if(!cipher_decrypt(c->incipher, bufp, inlen, buffer_prepare(&c->inbuf, inlen), &outlen, false) || inlen != outlen) { diff --git a/src/mingw/device.c b/src/mingw/device.c index b047615..dfdb964 100644 --- a/src/mingw/device.c +++ b/src/mingw/device.c @@ -214,6 +214,9 @@ static bool setup_device(void) { logger(DEBUG_ALWAYS, LOG_INFO, "%s (%s) is a %s", device, iface, device_info); + device_read_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + device_write_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + return true; } @@ -226,9 +229,6 @@ static void enable_device(void) { /* We don't use the write event directly, but GetOverlappedResult() does, internally. */ - device_read_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - device_write_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - io_add_event(&device_read_io, device_handle_read, NULL, device_read_overlapped.hEvent); device_issue_read(); } @@ -237,6 +237,19 @@ static void disable_device(void) { logger(DEBUG_ALWAYS, LOG_INFO, "Disabling %s", device_info); io_del(&device_read_io); + + ULONG status = 0; + DWORD len; + DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof status, &status, sizeof status, &len, NULL); + + /* Note that we don't try to cancel ongoing I/O here - we just stop listening. + This is because some TAP-Win32 drivers don't seem to handle cancellation very well, + especially when combined with other events such as the computer going to sleep - cases + were observed where the GetOverlappedResult() would just block indefinitely and never + return in that case. */ +} + +static void close_device(void) { CancelIo(device_handle); /* According to MSDN, CancelIo() does not necessarily wait for the operation to complete. @@ -253,11 +266,6 @@ static void disable_device(void) { CloseHandle(device_read_overlapped.hEvent); CloseHandle(device_write_overlapped.hEvent); - ULONG status = 0; - DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof status, &status, sizeof status, &len, NULL); -} - -static void close_device(void) { CloseHandle(device_handle); device_handle = INVALID_HANDLE_VALUE; free(device); device = NULL; diff --git a/src/names.c b/src/names.c index 6c518f2..0cae28a 100644 --- a/src/names.c +++ b/src/names.c @@ -1,7 +1,7 @@ /* names.c -- generate commonly used (file)names Copyright (C) 1998-2005 Ivo Timmermans - 2000-2015 Guus Sliepen + 2000-2017 Guus Sliepen 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 @@ -25,6 +25,7 @@ #include "xalloc.h" char *netname = NULL; +char *myname = NULL; char *confdir = NULL; /* base configuration directory */ char *confbase = NULL; /* base configuration directory for this instance of tinc */ bool confbase_given; @@ -137,6 +138,7 @@ void free_names(void) { free(logfilename); free(confbase); free(confdir); + free(myname); identname = NULL; netname = NULL; @@ -145,4 +147,5 @@ void free_names(void) { logfilename = NULL; confbase = NULL; confdir = NULL; + myname = NULL; } diff --git a/src/names.h b/src/names.h index a2395af..e6b99c5 100644 --- a/src/names.h +++ b/src/names.h @@ -1,7 +1,7 @@ /* names.h -- header for names.c Copyright (C) 1998-2005 Ivo Timmermans - 2000-2015 Guus Sliepen + 2000-2017 Guus Sliepen 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 @@ -25,6 +25,7 @@ extern char *confdir; extern char *confbase; extern bool confbase_given; extern char *netname; +extern char *myname; extern char *identname; extern char *unixsocketname; extern char *logfilename; diff --git a/src/net.c b/src/net.c index 4369ff4..1cb467d 100644 --- a/src/net.c +++ b/src/net.c @@ -1,7 +1,7 @@ /* net.c -- most of the network code Copyright (C) 1998-2005 Ivo Timmermans, - 2000-2015 Guus Sliepen + 2000-2017 Guus Sliepen 2006 Scott Lamb 2011 Loïc Grenié @@ -22,7 +22,7 @@ #include "system.h" -#include "utils.h" +#include "autoconnect.h" #include "conf.h" #include "connection.h" #include "device.h" @@ -34,6 +34,7 @@ #include "netutl.h" #include "protocol.h" #include "subnet.h" +#include "utils.h" #include "xalloc.h" int contradicting_add_edge = 0; @@ -209,7 +210,7 @@ static void timeout_handler(void *data) { // timeout during ping 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.tv_sec - c->last_ping_time); + logger(DEBUG_CONNECTIONS, LOG_INFO, "%s (%s) didn't respond to PING in %ld seconds", c->name, c->hostname, (long)(now.tv_sec - c->last_ping_time)); terminate_connection(c, c->edge); continue; } @@ -245,105 +246,9 @@ static void periodic_handler(void *data) { /* 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->edge) - nc++; - } + if(autoconnect && node_tree->count > 1) + do_autoconnect(); - if(nc < 3) { - /* 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 count = 0; - for splay_each(node_t, n, node_tree) { - if(n == myself || n->connection || !(n->status.has_address || n->status.reachable)) - continue; - count++; - } - - if(!count) - goto end; - - int r = rand() % count; - - for splay_each(node_t, n, node_tree) { - if(n == myself || n->connection || !(n->status.has_address || n->status.reachable)) - continue; - - if(r--) - continue; - - 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 = xzalloc(sizeof *outgoing); - outgoing->name = xstrdup(n->name); - list_insert_tail(outgoing_list, outgoing); - setup_outgoing_connection(outgoing); - } - - break; - } - } else if(nc > 3) { - /* 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->edge) - 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->edge); - break; - } - } - - if(nc >= 3) { - /* 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); - } - } - } - } - -end: timeout_set(data, &(struct timeval){5, rand() % 100000}); } diff --git a/src/net.h b/src/net.h index 7080869..69ca488 100644 --- a/src/net.h +++ b/src/net.h @@ -126,8 +126,9 @@ typedef struct outgoing_t { int timeout; splay_tree_t *config_tree; struct config_t *cfg; - struct addrinfo *ai; + struct addrinfo *ai; // addresses from config files struct addrinfo *aip; + struct addrinfo *kai; // addresses known via other online nodes (use free_known_addresses()) timeout_t ev; } outgoing_t; diff --git a/src/net_packet.c b/src/net_packet.c index 71f02a1..5d559bd 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -1,7 +1,7 @@ /* net_packet.c -- Handles in- and outgoing VPN packets Copyright (C) 1998-2005 Ivo Timmermans, - 2000-2016 Guus Sliepen + 2000-2017 Guus Sliepen 2010 Timothy Redaelli 2010 Brandon Black @@ -846,6 +846,7 @@ bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t vpn_packet_t inpkt; inpkt.offset = DEFAULT_PACKET_OFFSET; + inpkt.priority = 0; if(type == PKT_PROBE) { if(!from->status.udppacket) { @@ -1573,10 +1574,19 @@ void handle_device_data(void *data, int flags) { vpn_packet_t packet; packet.offset = DEFAULT_PACKET_OFFSET; packet.priority = 0; + static int errors = 0; if(devops.read(&packet)) { + errors = 0; myself->in_packets++; myself->in_bytes += packet.len; route(myself, &packet); + } else { + usleep(errors * 50000); + errors++; + if(errors > 10) { + logger(DEBUG_ALWAYS, LOG_ERR, "Too many errors from %s, exiting!", device); + event_exit(); + } } } diff --git a/src/net_setup.c b/src/net_setup.c index b0a0c95..e164214 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -1,7 +1,7 @@ /* net_setup.c -- Setup. Copyright (C) 1998-2005 Ivo Timmermans, - 2000-2016 Guus Sliepen + 2000-2017 Guus Sliepen 2006 Scott Lamb 2010 Brandon Black @@ -48,7 +48,6 @@ #endif char *myport; -static char *myname; static io_t device_io; devops_t devops; bool device_standby = false; @@ -612,6 +611,9 @@ bool setup_myself_reloadable(void) { get_config_bool(lookup_config(config_tree, "DisableBuggyPeers"), &disablebuggypeers); + if(!get_config_int(lookup_config(config_tree, "InvitationExpire"), &invitation_lifetime)) + invitation_lifetime = 604800; // 1 week + read_invitation_key(); return true; @@ -705,29 +707,17 @@ void device_enable(void) { /* Run tinc-up script to further initialize the tap interface */ - char *envp[5] = {NULL}; - xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); - xasprintf(&envp[1], "DEVICE=%s", device ? : ""); - xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); - xasprintf(&envp[3], "NAME=%s", myname); - - execute_script("tinc-up", envp); - - for(int i = 0; i < 4; i++) - free(envp[i]); + environment_t env; + environment_init(&env); + execute_script("tinc-up", &env); + environment_exit(&env); } void device_disable(void) { - char *envp[5] = {NULL}; - xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); - xasprintf(&envp[1], "DEVICE=%s", device ? : ""); - xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); - xasprintf(&envp[3], "NAME=%s", myname); - - execute_script("tinc-down", envp); - - for(int i = 0; i < 4; i++) - free(envp[i]); + environment_t env; + environment_init(&env); + execute_script("tinc-down", &env); + environment_exit(&env); if (devops.disable) devops.disable(); @@ -857,7 +847,7 @@ static bool setup_myself(void) { /* Generate packet encryption key */ if(!get_config_string(lookup_config(config_tree, "Cipher"), &cipher)) - cipher = xstrdup("blowfish"); + cipher = xstrdup("aes-256-cbc"); if(!strcasecmp(cipher, "none")) { myself->incipher = NULL; @@ -881,7 +871,7 @@ static bool setup_myself(void) { } if(!get_config_string(lookup_config(config_tree, "Digest"), &digest)) - digest = xstrdup("sha1"); + digest = xstrdup("sha256"); if(!strcasecmp(digest, "none")) { myself->indigest = NULL; @@ -929,6 +919,8 @@ static bool setup_myself(void) { devops = raw_socket_devops; else if(!strcasecmp(type, "multicast")) devops = multicast_devops; + else if(!strcasecmp(type, "fd")) + devops = fd_devops; #ifdef ENABLE_UML else if(!strcasecmp(type, "uml")) devops = uml_devops; @@ -1148,7 +1140,6 @@ void close_network_connections(void) { exit_control(); - free(myname); free(scriptextension); free(scriptinterpreter); diff --git a/src/net_socket.c b/src/net_socket.c index 8259d9a..ac6b840 100644 --- a/src/net_socket.c +++ b/src/net_socket.c @@ -1,7 +1,7 @@ /* net_socket.c -- Handle various kinds of sockets. Copyright (C) 1998-2005 Ivo Timmermans, - 2000-2016 Guus Sliepen + 2000-2017 Guus Sliepen 2006 Scott Lamb 2009 Florian Forster @@ -382,7 +382,7 @@ static void handle_meta_write(connection_t *c) { if(!sockerrno || sockerrno == EPIPE) { logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection closed by %s (%s)", c->name, c->hostname); } else if(sockwouldblock(sockerrno)) { - logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Sending %d bytes to %s (%s) would block", c->outbuf.len - c->outbuf.offset, c->name, c->hostname); + logger(DEBUG_META, LOG_DEBUG, "Sending %d bytes to %s (%s) would block", c->outbuf.len - c->outbuf.offset, c->name, c->hostname); return; } else { logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not send %d bytes of data to %s (%s): %s", c->outbuf.len - c->outbuf.offset, c->name, c->hostname, sockstrerror(sockerrno)); @@ -441,13 +441,20 @@ static void handle_meta_io(void *data, int flags) { handle_meta_connection_data(c); } +static void free_known_addresses(struct addrinfo *ai) { + for(struct addrinfo *aip = ai, *next; aip; aip = next) { + next = aip->ai_next; + free(aip); + } +} + bool do_outgoing_connection(outgoing_t *outgoing) { char *address, *port, *space; struct addrinfo *proxyai = NULL; int result; begin: - if(!outgoing->ai) { + if(!outgoing->ai && !outgoing->kai) { if(!outgoing->cfg) { logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not set up a meta connection to %s", outgoing->name); retry_outgoing(outgoing); @@ -477,6 +484,11 @@ begin: if(outgoing->ai) freeaddrinfo(outgoing->ai); outgoing->ai = NULL; + + if(outgoing->kai) + free_known_addresses(outgoing->kai); + outgoing->kai = NULL; + goto begin; } @@ -570,6 +582,7 @@ begin: // Find edges pointing to this node, and use them to build a list of unique, known addresses. static struct addrinfo *get_known_addresses(node_t *n) { struct addrinfo *ai = NULL; + struct addrinfo *oai = NULL; for splay_each(edge_t, e, n->edge_tree) { if(!e->reverse) @@ -585,16 +598,15 @@ static struct addrinfo *get_known_addresses(node_t *n) { if(found) continue; - struct addrinfo *nai = xzalloc(sizeof *nai); - if(ai) - ai->ai_next = nai; - ai = nai; + oai = ai; + ai = xzalloc(sizeof *ai); ai->ai_family = e->reverse->address.sa.sa_family; ai->ai_socktype = SOCK_STREAM; ai->ai_protocol = IPPROTO_TCP; ai->ai_addrlen = SALEN(e->reverse->address.sa); ai->ai_addr = xmalloc(ai->ai_addrlen); memcpy(ai->ai_addr, &e->reverse->address, ai->ai_addrlen); + ai->ai_next = oai; } return ai; @@ -621,8 +633,8 @@ void setup_outgoing_connection(outgoing_t *outgoing) { if(!outgoing->cfg) { if(n) - outgoing->aip = outgoing->ai = get_known_addresses(n); - if(!outgoing->ai) { + outgoing->aip = outgoing->kai = get_known_addresses(n); + if(!outgoing->kai) { logger(DEBUG_ALWAYS, LOG_DEBUG, "No address known for %s", outgoing->name); goto remove; } @@ -777,6 +789,9 @@ static void free_outgoing(outgoing_t *outgoing) { if(outgoing->ai) freeaddrinfo(outgoing->ai); + if(outgoing->kai) + free_known_addresses(outgoing->kai); + if(outgoing->config_tree) exit_configuration(&outgoing->config_tree); diff --git a/src/node.c b/src/node.c index 7242e95..b17e692 100644 --- a/src/node.c +++ b/src/node.c @@ -186,9 +186,9 @@ bool dump_nodes(connection_t *c) { for splay_each(node_t, n, node_tree) { char id[2 * sizeof n->id + 1]; for (size_t c = 0; c < sizeof n->id; ++c) - snprintf(id + 2 * c, 3, "%02hhx", n->id.x[c]); + snprintf(id + 2 * c, 3, "%02x", n->id.x[c]); id[sizeof id - 1] = 0; - send_request(c, "%d %d %s %s %s %d %d %d %d %x %x %s %s %d %hd %hd %hd %ld", CONTROL, REQ_DUMP_NODES, + send_request(c, "%d %d %s %s %s %d %d %d %d %x %x %s %s %d %d %d %d %ld", CONTROL, REQ_DUMP_NODES, n->name, id, n->hostname ?: "unknown port unknown", #ifdef DISABLE_LEGACY 0, 0, 0, diff --git a/src/openssl/cipher.c b/src/openssl/cipher.c index ae9640f..98033c5 100644 --- a/src/openssl/cipher.c +++ b/src/openssl/cipher.c @@ -1,6 +1,6 @@ /* cipher.c -- Symmetric block cipher handling - Copyright (C) 2007-2013 Guus Sliepen + Copyright (C) 2007-2017 Guus Sliepen 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 @@ -62,10 +62,6 @@ cipher_t *cipher_open_by_nid(int nid) { return cipher_open(evp_cipher); } -cipher_t *cipher_open_blowfish_ofb(void) { - return cipher_open(EVP_bf_ofb()); -} - void cipher_close(cipher_t *cipher) { if(!cipher) return; @@ -81,6 +77,24 @@ size_t cipher_keylength(const cipher_t *cipher) { return EVP_CIPHER_key_length(cipher->cipher) + EVP_CIPHER_iv_length(cipher->cipher); } +uint64_t cipher_budget(const cipher_t *cipher) { + /* Hopefully some failsafe way to calculate the maximum amount of bytes to + send/receive with a given cipher before we might run into birthday paradox + attacks. Because we might use different modes, the block size of the mode + might be 1 byte. In that case, use the IV length. Ensure the whole thing + is limited to what can be represented with a 64 bits integer. + */ + + if(!cipher || !cipher->cipher) + return UINT64_MAX; // NULL cipher + + int ivlen = EVP_CIPHER_iv_length(cipher->cipher); + int blklen = EVP_CIPHER_block_size(cipher->cipher); + int len = blklen > 1 ? blklen : ivlen > 1 ? ivlen : 8; + int bits = len * 4 - 1; + return bits < 64 ? UINT64_C(1) << bits : UINT64_MAX; +} + size_t cipher_blocksize(const cipher_t *cipher) { if(!cipher || !cipher->cipher) return 1; @@ -123,7 +137,7 @@ bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou int len, pad; if(EVP_EncryptInit_ex(cipher->ctx, NULL, NULL, NULL, NULL) && EVP_EncryptUpdate(cipher->ctx, (unsigned char *)outdata, &len, indata, inlen) - && EVP_EncryptFinal(cipher->ctx, (unsigned char *)outdata + len, &pad)) { + && EVP_EncryptFinal_ex(cipher->ctx, (unsigned char *)outdata + len, &pad)) { if(outlen) *outlen = len + pad; return true; } @@ -144,7 +158,7 @@ bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou int len, pad; if(EVP_DecryptInit_ex(cipher->ctx, NULL, NULL, NULL, NULL) && EVP_DecryptUpdate(cipher->ctx, (unsigned char *)outdata, &len, indata, inlen) - && EVP_DecryptFinal(cipher->ctx, (unsigned char *)outdata + len, &pad)) { + && EVP_DecryptFinal_ex(cipher->ctx, (unsigned char *)outdata + len, &pad)) { if(outlen) *outlen = len + pad; return true; } diff --git a/src/openssl/digest.c b/src/openssl/digest.c index c303785..58ca167 100644 --- a/src/openssl/digest.c +++ b/src/openssl/digest.c @@ -1,6 +1,6 @@ /* digest.c -- Digest handling - Copyright (C) 2007-2013 Guus Sliepen + Copyright (C) 2007-2016 Guus Sliepen 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 @@ -64,10 +64,6 @@ digest_t *digest_open_by_nid(int nid, int maclength) { return digest_open(evp_md, maclength); } -digest_t *digest_open_sha1(int maclength) { - return digest_open(EVP_sha1(), maclength); -} - bool digest_set_key(digest_t *digest, const void *key, size_t len) { digest->key = xrealloc(digest->key, len); memcpy(digest->key, key, len); diff --git a/src/protocol.h b/src/protocol.h index dee6eb8..8ce4e0d 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -1,7 +1,7 @@ /* protocol.h -- header for protocol.c Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2013 Guus Sliepen + 2000-2017 Guus Sliepen 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 @@ -62,6 +62,7 @@ extern bool tunnelserver; extern bool strictsubnets; extern bool experimental; +extern int invitation_lifetime; extern ecdsa_t *invitation_key; /* Maximum size of strings in a request. diff --git a/src/protocol_auth.c b/src/protocol_auth.c index 31b1f1e..a99e1d6 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -1,7 +1,7 @@ /* protocol_auth.c -- handle the meta-protocol, authentication Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2014 Guus Sliepen + 2000-2017 Guus Sliepen 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 @@ -47,6 +47,7 @@ #include "ed25519/sha512.h" +int invitation_lifetime; ecdsa_t *invitation_key = NULL; static bool send_proxyrequest(connection_t *c) { @@ -180,21 +181,18 @@ static bool finalize_invitation(connection_t *c, const char *data, uint16_t len) logger(DEBUG_CONNECTIONS, LOG_INFO, "Key succesfully received from %s (%s)", c->name, c->hostname); // Call invitation-accepted script - char *envp[7] = {NULL}; + environment_t env; char *address, *port; - xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); - xasprintf(&envp[1], "DEVICE=%s", device ? : ""); - xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); - xasprintf(&envp[3], "NODE=%s", c->name); + environment_init(&env); + environment_add(&env, "NODE=%s", c->name); sockaddr2str(&c->address, &address, &port); - xasprintf(&envp[4], "REMOTEADDRESS=%s", address); - xasprintf(&envp[5], "NAME=%s", myself->name); + environment_add(&env, "REMOTEADDRESS=%s", address); + environment_add(&env, "NAME=%s", myself->name); - execute_script("invitation-accepted", envp); + execute_script("invitation-accepted", &env); - for(int i = 0; envp[i] && i < 7; i++) - free(envp[i]); + environment_exit(&env); sptps_send_record(&c->sptps, 2, data, 0); return true; @@ -235,6 +233,18 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const void *dat return false; } + // Check the timestamp of the invitation + struct stat st; + if(stat(usedname, &st)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not stat %s", usedname); + return false; + } + + if(st.st_mtime + invitation_lifetime < now.tv_sec) { + logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s tried to use expired invitation %s", c->hostname, cookie); + return false; + } + // Open the renamed file FILE *f = fopen(usedname, "r"); if(!f) { @@ -284,7 +294,7 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const void *dat bool id_h(connection_t *c, const char *request) { char name[MAX_STRING_SIZE]; - if(sscanf(request, "%*d " MAX_STRING " %d.%d", name, &c->protocol_major, &c->protocol_minor) < 2) { + if(sscanf(request, "%*d " MAX_STRING " %2d.%3d", name, &c->protocol_major, &c->protocol_minor) < 2) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ID", c->name, c->hostname); return false; @@ -421,10 +431,24 @@ bool send_metakey(connection_t *c) { if(!read_rsa_public_key(c)) return false; - if(!(c->outcipher = cipher_open_blowfish_ofb())) + /* We need to use a stream mode for the meta protocol. Use AES for this, + but try to match the key size with the one from the cipher selected + by Cipher. + */ + + int keylen = cipher_keylength(myself->incipher); + if(keylen <= 16) + c->outcipher = cipher_open_by_name("aes-128-cfb"); + else if(keylen <= 24) + c->outcipher = cipher_open_by_name("aes-192-cfb"); + else + c->outcipher = cipher_open_by_name("aes-256-cfb"); + if(!c) return false; - if(!(c->outdigest = digest_open_sha1(-1))) + c->outbudget = cipher_budget(c->outcipher); + + if(!(c->outdigest = digest_open_by_name("sha256", -1))) return false; const size_t len = rsa_size(c->rsa); @@ -536,6 +560,8 @@ bool metakey_h(connection_t *c, const char *request) { c->incipher = NULL; } + c->inbudget = cipher_budget(c->incipher); + if(digest) { if(!(c->indigest = digest_open_by_nid(digest, -1))) { logger(DEBUG_ALWAYS, LOG_ERR, "Error during initialisation of digest from %s (%s)", c->name, c->hostname); @@ -872,8 +898,10 @@ bool ack_h(connection_t *c, const char *request) { socklen_t local_salen = sizeof local_sa; if (getsockname(c->socket, &local_sa.sa, &local_salen) < 0) logger(DEBUG_ALWAYS, LOG_WARNING, "Could not get local socket address for connection with %s", c->name); - else + else { sockaddr_setport(&local_sa, myport); + c->edge->local_address = local_sa; + } c->edge->weight = (weight + c->estimated_weight) / 2; c->edge->connection = c; c->edge->options = c->options; diff --git a/src/protocol_edge.c b/src/protocol_edge.c index dc0cf05..92089b1 100644 --- a/src/protocol_edge.c +++ b/src/protocol_edge.c @@ -132,63 +132,52 @@ bool add_edge_h(connection_t *c, const char *request) { e = lookup_edge(from, to); if(e) { - if(e->weight != weight || e->options != options || sockaddrcmp(&e->address, &address)) { - if(from == myself) { - logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself which does not match existing entry", - "ADD_EDGE", c->name, c->hostname); - send_add_edge(c, e); - sockaddrfree(&local_address); - return true; - } else { - logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) which does not match existing entry", - "ADD_EDGE", c->name, c->hostname); - e->options = options; - if(sockaddrcmp(&e->address, &address)) { - sockaddrfree(&e->address); - e->address = address; - } - if(e->weight != weight) { - splay_node_t *node = splay_unlink(edge_weight_tree, e); - e->weight = weight; - splay_insert_node(edge_weight_tree, node); - } + bool new_address = sockaddrcmp(&e->address, &address); + // local_address.sa.sa_family will be 0 if we got it from older tinc versions + // local_address.sa.sa_family will be 255 (AF_UNKNOWN) if we got it from newer versions + // but for edge which does not have local_address + bool new_local_address = local_address.sa.sa_family && local_address.sa.sa_family != AF_UNKNOWN && + sockaddrcmp(&e->local_address, &local_address); - goto done; - } - } else if(sockaddrcmp(&e->local_address, &local_address)) { - if(from == myself) { - if(e->local_address.sa.sa_family && local_address.sa.sa_family) { - // Someone has the wrong local address for ourself. Correct then. - logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself which does not match existing entry", - "ADD_EDGE", c->name, c->hostname); - send_add_edge(c, e); - sockaddrfree(&local_address); - return true; - } - // Otherwise, just ignore it. - sockaddrfree(&local_address); - return true; - } else if(local_address.sa.sa_family && local_address.sa.sa_family != AF_UNKNOWN) { - // We learned a new local address for this edge. - // local_address.sa.sa_family will be 0 if we got it from older tinc versions - // local_address.sa.sa_family will be 255 (AF_UNKNOWN) if we got it from newer versions - // but for edge which does not have local_address - sockaddrfree(&e->local_address); - e->local_address = local_address; - - // Tell others about it. - if(!tunnelserver) - forward_request(c, request); - - return true; - } else { - sockaddrfree(&local_address); - return true; - } - } else { + if(e->weight == weight && e->options == options && !new_address && !new_local_address) { + sockaddrfree(&address); sockaddrfree(&local_address); return true; } + + if(from == myself) { + logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself which does not match existing entry", + "ADD_EDGE", c->name, c->hostname); + send_add_edge(c, e); + sockaddrfree(&address); + sockaddrfree(&local_address); + return true; + } + + logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) which does not match existing entry", + "ADD_EDGE", c->name, c->hostname); + + e->options = options; + + if(new_address) { + sockaddrfree(&e->address); + e->address = address; + } else { + sockaddrfree(&address); + } + + if(new_local_address) { + sockaddrfree(&e->local_address); + e->local_address = local_address; + } else { + sockaddrfree(&local_address); + } + + if(e->weight != weight) { + splay_node_t *node = splay_unlink(edge_weight_tree, e); + e->weight = weight; + splay_insert_node(edge_weight_tree, node); + } } else if(from == myself) { logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself which does not exist", "ADD_EDGE", c->name, c->hostname); @@ -198,20 +187,20 @@ bool add_edge_h(connection_t *c, const char *request) { e->to = to; send_del_edge(c, e); free_edge(e); + sockaddrfree(&address); sockaddrfree(&local_address); return true; + } else { + e = new_edge(); + e->from = from; + e->to = to; + e->address = address; + e->local_address = local_address; + e->options = options; + e->weight = weight; + edge_add(e); } - e = new_edge(); - e->from = from; - e->to = to; - e->address = address; - e->local_address = local_address; - e->options = options; - e->weight = weight; - edge_add(e); - -done: /* Tell the rest about the new edge */ if(!tunnelserver) diff --git a/src/protocol_key.c b/src/protocol_key.c index d24d4ac..a18cefc 100644 --- a/src/protocol_key.c +++ b/src/protocol_key.c @@ -1,7 +1,7 @@ /* protocol_key.c -- handle the meta-protocol, key exchange Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2014 Guus Sliepen + 2000-2017 Guus Sliepen 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 @@ -356,7 +356,7 @@ bool ans_key_h(connection_t *c, const char *request) { char key[MAX_STRING_SIZE]; char address[MAX_STRING_SIZE] = ""; char port[MAX_STRING_SIZE] = ""; - int cipher, digest, maclength, compression, keylen; + int cipher, digest, maclength, compression; node_t *from, *to; if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %d %d "MAX_STRING" "MAX_STRING, @@ -489,7 +489,7 @@ bool ans_key_h(connection_t *c, const char *request) { /* Process key */ - keylen = hex2bin(key, key, sizeof key); + int keylen = hex2bin(key, key, sizeof key); if(keylen != (from->outcipher ? cipher_keylength(from->outcipher) : 1)) { logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname); diff --git a/src/protocol_misc.c b/src/protocol_misc.c index 95bd322..05a4ada 100644 --- a/src/protocol_misc.c +++ b/src/protocol_misc.c @@ -135,7 +135,7 @@ bool send_tcppacket(connection_t *c, const vpn_packet_t *packet) { if(2.0 * c->outbuf.len / (float)maxoutbufsize - 1 > (float)rand()/(float)RAND_MAX) return true; - if(!send_request(c, "%d %hd", PACKET, packet->len)) + if(!send_request(c, "%d %d", PACKET, packet->len)) return false; return send_meta(c, (char *)DATA(packet), packet->len); @@ -194,6 +194,11 @@ bool send_udp_info(node_t *from, node_t *to) { farther than the static relay. */ to = (to->via == myself) ? to->nexthop : to->via; + if (to == NULL) { + logger(DEBUG_ALWAYS, LOG_ERR, "Something went wrong when selecting relay - possible fake UDP_INFO"); + return false; + } + /* Skip cases where sending UDP info messages doesn't make sense. This is done here in order to avoid repeating the same logic in multiple callsites. */ diff --git a/src/route.c b/src/route.c index 0c9f2aa..7ae4960 100644 --- a/src/route.c +++ b/src/route.c @@ -510,7 +510,7 @@ static void route_broadcast(node_t *source, 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; + int maxlen, todo; uint8_t *offset; uint16_t ip_off, origf; @@ -537,7 +537,7 @@ static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t et ip_off &= IP_OFFMASK; while(todo) { - len = todo > maxlen ? maxlen : todo; + int len = todo > maxlen ? maxlen : todo; memcpy(DATA(&fragment) + ether_size + ip_size, offset, len); todo -= len; offset += len; @@ -683,6 +683,9 @@ static void route_ipv6(node_t *source, vpn_packet_t *packet) { if(!do_decrement_ttl(source, packet)) return; + if(priorityinheritance) + packet->priority = ((DATA(packet)[14] & 0x0f) << 4) | (DATA(packet)[15] >> 4); + via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via; if(via == source) { @@ -954,8 +957,12 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { uint16_t type = DATA(packet)[12] << 8 | DATA(packet)[13]; - if(priorityinheritance && type == ETH_P_IP && packet->len >= ether_size + ip_size) - packet->priority = DATA(packet)[15]; + if(priorityinheritance) { + if(type == ETH_P_IP && packet->len >= ether_size + ip_size) + packet->priority = DATA(packet)[15]; + else if(type == ETH_P_IPV6 && packet->len >= ether_size + ip6_size) + packet->priority = ((DATA(packet)[14] & 0x0f) << 4) | (DATA(packet)[15] >> 4); + } // Handle packets larger than PMTU diff --git a/src/script.c b/src/script.c index d4db889..d65551a 100644 --- a/src/script.c +++ b/src/script.c @@ -1,7 +1,7 @@ /* script.c -- call an external script Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2015 Guus Sliepen + 2000-2017 Guus Sliepen 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 @@ -21,6 +21,7 @@ #include "system.h" #include "conf.h" +#include "device.h" #include "logger.h" #include "names.h" #include "script.h" @@ -63,7 +64,58 @@ static void putenv(const char *p) {} static void unputenv(const char *p) {} #endif -bool execute_script(const char *name, char **envp) { +static const int min_env_size = 10; + +int environment_add(environment_t *env, const char *format, ...) { + if(env->n >= env->size) { + env->size = env->n ? env->n * 2 : min_env_size; + env->entries = xrealloc(env->entries, env->size * sizeof *env->entries); + } + + if(format) { + va_list ap; + va_start(ap, format); + vasprintf(&env->entries[env->n], format, ap); + va_end(ap); + } else { + env->entries[env->n] = NULL; + } + + return env->n++; +} + +void environment_update(environment_t *env, int pos, const char *format, ...) { + free(env->entries[pos]); + va_list ap; + va_start(ap, format); + vasprintf(&env->entries[pos], format, ap); + va_end(ap); +} + +void environment_init(environment_t *env) { + env->n = 0; + env->size = min_env_size; + env->entries = xzalloc(env->size * sizeof *env->entries); + + if(netname) + environment_add(env, "NETNAME=%s", netname); + if(myname) + environment_add(env, "NAME=%s", myname); + if(device) + environment_add(env, "DEVICE=%s", device); + if(iface) + environment_add(env, "INTERFACE=%s", iface); + if(debug_level >= 0) + environment_add(env, "DEBUG=%d", debug_level); +} + +void environment_exit(environment_t *env) { + for(int i = 0; i < env->n; i++) + free(env->entries[i]); + free(env->entries); +} + +bool execute_script(const char *name, environment_t *env) { char scriptname[PATH_MAX]; char *command; @@ -107,8 +159,8 @@ bool execute_script(const char *name, char **envp) { /* Set environment */ - for(int i = 0; envp[i]; i++) - putenv(envp[i]); + for(int i = 0; i < env->n; i++) + putenv(env->entries[i]); if(scriptinterpreter) xasprintf(&command, "%s \"%s\"", scriptinterpreter, scriptname); @@ -121,8 +173,8 @@ bool execute_script(const char *name, char **envp) { /* Unset environment */ - for(int i = 0; envp[i]; i++) - unputenv(envp[i]); + for(int i = 0; i < env->n; i++) + unputenv(env->entries[i]); if(status != -1) { #ifdef WEXITSTATUS diff --git a/src/script.h b/src/script.h index 446a3b9..2e26418 100644 --- a/src/script.h +++ b/src/script.h @@ -1,7 +1,7 @@ /* script.h -- header file for script.c Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2013 Guus Sliepen + 2000-2017 Guus Sliepen 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 @@ -21,6 +21,18 @@ #ifndef __TINC_SCRIPT_H__ #define __TINC_SCRIPT_H__ -extern bool execute_script(const char *, char **); +typedef struct environment { + int n; + int size; + char **entries; +} environment_t; + +extern int environment_add(environment_t *env, const char *format, ...); +extern int environment_placeholder(environment_t *env); +extern void environment_update(environment_t *env, int pos, const char *format, ...); +extern void environment_init(environment_t *env); +extern void environment_exit(environment_t *env); + +extern bool execute_script(const char *name, environment_t *env); #endif /* __TINC_SCRIPT_H__ */ diff --git a/src/solaris/device.c b/src/solaris/device.c index fadae57..89481c7 100644 --- a/src/solaris/device.c +++ b/src/solaris/device.c @@ -24,6 +24,7 @@ #include #include +#include #include "../conf.h" #include "../device.h" @@ -41,6 +42,7 @@ #define DEFAULT_TUN_DEVICE "/dev/tun" #define DEFAULT_TAP_DEVICE "/dev/tap" +#define IP_DEVICE "/dev/udp" static enum { DEVICE_TYPE_TUN, @@ -84,8 +86,8 @@ static bool setup_device(void) { /* The following is black magic copied from OpenVPN. */ - if((ip_fd = open("/dev/ip", O_RDWR, 0)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s\n", "/dev/ip", strerror(errno)); + if((ip_fd = open(IP_DEVICE, O_RDWR, 0)) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s\n", IP_DEVICE, strerror(errno)); return false; } @@ -203,7 +205,7 @@ static bool setup_device(void) { /* Push arp module to ip_fd */ if(ioctl(ip_fd, I_PUSH, "arp") < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not push ARP module onto %s!", "/dev/ip"); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not push ARP module onto %s!", IP_DEVICE); return false; } @@ -295,11 +297,16 @@ static void close_device(void) { } static bool read_packet(vpn_packet_t *packet) { - int inlen; + int result; + struct strbuf sbuf; + int f = 0; switch(device_type) { case DEVICE_TYPE_TUN: - if((inlen = read(device_fd, DATA(packet) + 14, MTU - 14)) <= 0) { + sbuf.maxlen = MTU - 14; + sbuf.buf = (char *)DATA(packet) + 14; + + if((result = getmsg(device_fd, NULL, &sbuf, &f)) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); return false; } @@ -319,16 +326,19 @@ static bool read_packet(vpn_packet_t *packet) { } memset(DATA(packet), 0, 12); - packet->len = inlen + 14; + packet->len = sbuf.len + 14; break; case DEVICE_TYPE_TAP: - if((inlen = read(device_fd, DATA(packet), MTU)) <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); + sbuf.maxlen = MTU; + sbuf.buf = (char *)DATA(packet); + + if((result = getmsg(device_fd, NULL, &sbuf, &f)) < 0) { + logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); return false; } - packet->len = inlen + 14; + packet->len = sbuf.len; break; default: @@ -343,17 +353,25 @@ static bool read_packet(vpn_packet_t *packet) { static bool write_packet(vpn_packet_t *packet) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", packet->len, device_info); + struct strbuf sbuf; + switch(device_type) { case DEVICE_TYPE_TUN: - if(write(device_fd, DATA(packet) + 14, packet->len - 14) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); + sbuf.len = packet->len - 14; + sbuf.buf = (char *)DATA(packet) + 14; + + if(putmsg(device_fd, NULL, &sbuf, 0) < 0) { + logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); return false; } break; case DEVICE_TYPE_TAP: - if(write(device_fd, DATA(packet), packet->len) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); + sbuf.len = packet->len; + sbuf.buf = (char *)DATA(packet); + + if(putmsg(device_fd, NULL, &sbuf, 0) < 0) { + logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); return false; } break; diff --git a/src/sptps_test.c b/src/sptps_test.c index a394175..8df1046 100644 --- a/src/sptps_test.c +++ b/src/sptps_test.c @@ -44,6 +44,7 @@ static bool readonly; static bool writeonly; static int in = 0; static int out = 1; +static int addressfamily = AF_UNSPEC; static bool send_data(void *handle, uint8_t type, const void *data, size_t len) { char hex[len * 2 + 1]; @@ -58,7 +59,7 @@ static bool send_data(void *handle, uint8_t type, const void *data, size_t len) static bool receive_record(void *handle, uint8_t type, const void *data, uint16_t len) { if(verbose) - fprintf(stderr, "Received type %d record of %hu bytes:\n", type, len); + fprintf(stderr, "Received type %d record of %u bytes:\n", type, len); if(!writeonly) write(out, data, len); return true; @@ -93,6 +94,8 @@ static void usage() { " -R, --replay-window N Set replay window to N bytes.\n" " -s, --special Enable special handling of lines starting with #, ^ and $.\n" " -v, --verbose Display debug messages.\n" + " -4 Use IPv4.\n" + " -6 Use IPv6.\n" "\n"); fprintf(stderr, "Report bugs to tinc@tinc-vpn.org.\n"); } @@ -110,7 +113,7 @@ int main(int argc, char *argv[]) { ecdsa_t *mykey = NULL, *hiskey = NULL; bool quit = false; - while((r = getopt_long(argc, argv, "dqrstwL:W:v", long_options, &option_index)) != EOF) { + while((r = getopt_long(argc, argv, "dqrstwL:W:v46", long_options, &option_index)) != EOF) { switch (r) { case 0: /* long option */ break; @@ -161,6 +164,14 @@ int main(int argc, char *argv[]) { usage(); return 1; + case '4': /* IPv4 */ + addressfamily = AF_INET; + break; + + case '6': /* IPv6 */ + addressfamily = AF_INET6; + break; + case 1: /* help */ usage(); return 0; @@ -212,7 +223,7 @@ int main(int argc, char *argv[]) { struct addrinfo *ai, hint; memset(&hint, 0, sizeof hint); - hint.ai_family = AF_UNSPEC; + hint.ai_family = addressfamily; hint.ai_socktype = datagram ? SOCK_DGRAM : SOCK_STREAM; hint.ai_protocol = datagram ? IPPROTO_UDP : IPPROTO_TCP; hint.ai_flags = initiator ? 0 : AI_PASSIVE; diff --git a/src/subnet.c b/src/subnet.c index 090a62b..3d055b6 100644 --- a/src/subnet.c +++ b/src/subnet.c @@ -1,6 +1,6 @@ /* subnet.c -- handle subnet lookups and lists - Copyright (C) 2000-2013 Guus Sliepen , + Copyright (C) 2000-2017 Guus Sliepen , 2000-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -206,22 +206,20 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) { // Prepare environment variables to be passed to the script - char *envp[10] = {NULL}; - int n = 0; - xasprintf(&envp[n++], "NETNAME=%s", netname ? : ""); - xasprintf(&envp[n++], "DEVICE=%s", device ? : ""); - xasprintf(&envp[n++], "INTERFACE=%s", iface ? : ""); - xasprintf(&envp[n++], "NODE=%s", owner->name); + environment_t env; + environment_init(&env); + environment_add(&env, "NODE=%s", owner->name); if(owner != myself) { sockaddr2str(&owner->address, &address, &port); - xasprintf(&envp[n++], "REMOTEADDRESS=%s", address); - xasprintf(&envp[n++], "REMOTEPORT=%s", port); + environment_add(&env, "REMOTEADDRESS=%s", address); + environment_add(&env, "REMOTEPORT=%s", port); free(port); free(address); } - xasprintf(&envp[n++], "NAME=%s", myself->name); + int env_subnet = environment_add(&env, NULL); + int env_weight = environment_add(&env, NULL); name = up ? "subnet-up" : "subnet-down"; @@ -238,12 +236,10 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) { weight = empty; // Prepare the SUBNET and WEIGHT variables - free(envp[n]); - free(envp[n + 1]); - xasprintf(&envp[n], "SUBNET=%s", netstr); - xasprintf(&envp[n + 1], "WEIGHT=%s", weight); + environment_update(&env, env_subnet, "SUBNET=%s", netstr); + environment_update(&env, env_weight, "WEIGHT=%s", weight); - execute_script(name, envp); + execute_script(name, &env); } } else { if(net2str(netstr, sizeof netstr, subnet)) { @@ -255,15 +251,14 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) { weight = empty; // Prepare the SUBNET and WEIGHT variables - xasprintf(&envp[n], "SUBNET=%s", netstr); - xasprintf(&envp[n + 1], "WEIGHT=%s", weight); + environment_update(&env, env_subnet, "SUBNET=%s", netstr); + environment_update(&env, env_weight, "WEIGHT=%s", weight); - execute_script(name, envp); + execute_script(name, &env); } } - for(int i = 0; envp[i] && i < 9; i++) - free(envp[i]); + environment_exit(&env); } bool dump_subnets(connection_t *c) { diff --git a/src/subnet_parse.c b/src/subnet_parse.c index 611d6bd..c5f6976 100644 --- a/src/subnet_parse.c +++ b/src/subnet_parse.c @@ -372,7 +372,7 @@ bool net2str(char *netstr, int len, const subnet_t *subnet) { result = snprintf(netstr, len, *format, ":::"); i += max_zero_length; } else { - result = snprintf(netstr, len, "%hx:", ntohs(subnet->net.ipv6.address.x[i])); + result = snprintf(netstr, len, "%x:", ntohs(subnet->net.ipv6.address.x[i])); i++; } netstr += result; diff --git a/src/tincctl.c b/src/tincctl.c index 465c981..9eb9a1b 100644 --- a/src/tincctl.c +++ b/src/tincctl.c @@ -1,6 +1,6 @@ /* tincctl.c -- Controlling a running tincd - Copyright (C) 2007-2016 Guus Sliepen + Copyright (C) 2007-2017 Guus Sliepen 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 @@ -74,6 +74,9 @@ bool netnamegiven = false; char *scriptinterpreter = NULL; char *scriptextension = ""; static char *prompt; +char *device = NULL; +char *iface = NULL; +int debug_level = -1; static struct option const long_options[] = { {"batch", no_argument, NULL, 'b'}, @@ -89,7 +92,7 @@ static struct option const long_options[] = { static void version(void) { printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE, BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR); - printf("Copyright (C) 1998-2016 Ivo Timmermans, Guus Sliepen and others.\n" + printf("Copyright (C) 1998-2017 Ivo Timmermans, Guus Sliepen and others.\n" "See the AUTHORS file for a complete list.\n\n" "tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n" "and you are welcome to redistribute it under certain conditions;\n" @@ -446,11 +449,13 @@ static bool rsa_keygen(int bits, bool ask) { // Make sure the key size is a multiple of 8 bits. bits &= ~0x7; - // Force them to be between 1024 and 8192 bits long. - if(bits < 1024) - bits = 1024; - if(bits > 8192) - bits = 8192; + // Make sure that a valid key size is used. + if(bits < 1024 || bits > 8192) { + fprintf(stderr, "Invalid key size %d specified! It should be between 1024 and 8192 bits.\n", bits); + return false; + } else if(bits < 2048) { + fprintf(stderr, "WARNING: generating a weak %d bits RSA key! 2048 or more bits are recommended.\n", bits); + } fprintf(stderr, "Generating %d bits keys:\n", bits); @@ -508,7 +513,7 @@ bool recvline(int fd, char *line, size_t len) { char *newline = NULL; if(!fd) - abort(); + return false; while(!(newline = memchr(buffer, '\n', blen))) { int result = recv(fd, buffer + blen, sizeof buffer - blen, 0); @@ -719,6 +724,8 @@ bool connect_tincd(bool verbose) { } fclose(f); + +#ifndef HAVE_MINGW if ((pid == 0) || (kill(pid, 0) && (errno == ESRCH))) { fprintf(stderr, "Could not find tincd running at pid %d\n", pid); /* clean up the stale socket and pid file */ @@ -727,7 +734,6 @@ bool connect_tincd(bool verbose) { return false; } -#ifndef HAVE_MINGW struct sockaddr_un sa; sa.sun_family = AF_UNIX; strncpy(sa.sun_path, unixsocketname, sizeof sa.sun_path); @@ -797,7 +803,7 @@ bool connect_tincd(bool verbose) { char data[4096]; int version; - if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %s %d", &code, data, &version) != 3 || code != 0) { + if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %4095s %d", &code, data, &version) != 3 || code != 0) { if(verbose) fprintf(stderr, "Cannot read greeting from control socket: %s\n", sockstrerror(sockerrno)); close(fd); @@ -945,11 +951,11 @@ static int cmd_stop(int argc, char *argv[]) { if(!connect_tincd(true)) { if(pid) { if(kill(pid, SIGTERM)) { - fprintf(stderr, "Could not send TERM signal to process with PID %u: %s\n", pid, strerror(errno)); + fprintf(stderr, "Could not send TERM signal to process with PID %d: %s\n", pid, strerror(errno)); return 1; } - fprintf(stderr, "Sent TERM signal to process with PID %u.\n", pid); + fprintf(stderr, "Sent TERM signal to process with PID %d.\n", pid); waitpid(pid, NULL, 0); return 0; } @@ -1024,7 +1030,6 @@ static int dump_invitations(void) { FILE *f = fopen(fname, "r"); if(!f) { fprintf(stderr, "Cannot open %s: %s\n", fname, strerror(errno)); - fclose(f); continue; } @@ -1113,7 +1118,7 @@ static int cmd_dump(int argc, char *argv[]) { while(recvline(fd, line, sizeof line)) { char node1[4096], node2[4096]; - int n = sscanf(line, "%d %d %s %s", &code, &req, node1, node2); + int n = sscanf(line, "%d %d %4095s %4095s", &code, &req, node1, node2); if(n == 2) { if(do_graph && req == REQ_DUMP_NODES) continue; @@ -1145,7 +1150,7 @@ static int cmd_dump(int argc, char *argv[]) { switch(req) { case REQ_DUMP_NODES: { - int n = sscanf(line, "%*d %*d %s %s %s port %s %d %d %d %d %x %x %s %s %d %hd %hd %hd %ld", node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_int, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change); + int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %d %d %d %d %x %x %4095s %4095s %d %hd %hd %hd %ld", node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_int, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change); if(n != 17) { fprintf(stderr, "Unable to parse node dump from tincd: %s\n", line); return 1; @@ -1169,13 +1174,13 @@ static int cmd_dump(int argc, char *argv[]) { } else { if(only_reachable && !status.reachable) continue; - printf("%s id %s at %s port %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %hd (min %hd max %hd)\n", + printf("%s id %s at %s port %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %d (min %d max %d)\n", node, id, host, port, cipher, digest, maclength, compression, options, status_int, nexthop, via, distance, pmtu, minmtu, maxmtu); } } break; case REQ_DUMP_EDGES: { - int n = sscanf(line, "%*d %*d %s %s %s port %s %s port %s %x %d", from, to, host, port, local_host, local_port, &options, &weight); + int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %4095s port %4095s %x %d", from, to, host, port, local_host, local_port, &options, &weight); if(n != 8) { fprintf(stderr, "Unable to parse edge dump from tincd.\n"); return 1; @@ -1193,7 +1198,7 @@ static int cmd_dump(int argc, char *argv[]) { } break; case REQ_DUMP_SUBNETS: { - int n = sscanf(line, "%*d %*d %s %s", subnet, node); + int n = sscanf(line, "%*d %*d %4095s %4095s", subnet, node); if(n != 2) { fprintf(stderr, "Unable to parse subnet dump from tincd.\n"); return 1; @@ -1202,7 +1207,7 @@ static int cmd_dump(int argc, char *argv[]) { } break; case REQ_DUMP_CONNECTIONS: { - int n = sscanf(line, "%*d %*d %s %s port %s %x %d %x", node, host, port, &options, &socket, &status_int); + int n = sscanf(line, "%*d %*d %4095s %4095s port %4095s %x %d %x", node, host, port, &options, &socket, &status_int); if(n != 6) { fprintf(stderr, "Unable to parse connection dump from tincd.\n"); return 1; @@ -1485,9 +1490,11 @@ const var_t variables[] = { {"Hostnames", VAR_SERVER}, {"IffOneQueue", VAR_SERVER}, {"Interface", VAR_SERVER}, + {"InvitationExpire", VAR_SERVER}, {"KeyExpire", VAR_SERVER}, {"ListenAddress", VAR_SERVER | VAR_MULTIPLE}, {"LocalDiscovery", VAR_SERVER}, + {"LogLevel", VAR_SERVER}, {"MACExpire", VAR_SERVER}, {"MaxConnectionBurst", VAR_SERVER}, {"MaxOutputBufferSize", VAR_SERVER}, @@ -2227,7 +2234,7 @@ static int cmd_import(int argc, char *argv[]) { bool firstline = true; while(fgets(buf, sizeof buf, in)) { - if(sscanf(buf, "Name = %s", name) == 1) { + if(sscanf(buf, "Name = %4095s", name) == 1) { firstline = false; if(!check_id(name)) { @@ -2719,7 +2726,7 @@ static char *complete_info(const char *text, int state) { while(recvline(fd, line, sizeof line)) { char item[4096]; - int n = sscanf(line, "%d %d %s", &code, &req, item); + int n = sscanf(line, "%d %d %4095s", &code, &req, item); if(n == 2) { i++; if(i >= 2) @@ -2820,8 +2827,6 @@ static int cmd_shell(int argc, char *argv[]) { while(p && *p) { if(nargc >= maxargs) { - fprintf(stderr, "next %p '%s', p %p '%s'\n", next, next, p, p); - abort(); maxargs *= 2; nargv = xrealloc(nargv, maxargs * sizeof *nargv); } diff --git a/src/tincd.c b/src/tincd.c index 4da9bd5..2ab9ba7 100644 --- a/src/tincd.c +++ b/src/tincd.c @@ -400,6 +400,9 @@ int main(int argc, char **argv) { if(!read_server_config()) return 1; + if(!debug_level) + get_config_int(lookup_config(config_tree, "LogLevel"), &debug_level); + #ifdef HAVE_LZO if(lzo_init() != LZO_E_OK) { logger(DEBUG_ALWAYS, LOG_ERR, "Error initializing LZO compressor!"); diff --git a/src/top.c b/src/top.c index 40b8047..8227d6c 100644 --- a/src/top.c +++ b/src/top.c @@ -90,7 +90,7 @@ static bool update(int fd) { ns->known = false; while(recvline(fd, line, sizeof line)) { - int n = sscanf(line, "%d %d %s %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, &code, &req, name, &in_packets, &in_bytes, &out_packets, &out_bytes); + int n = sscanf(line, "%d %d %4095s %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, &code, &req, name, &in_packets, &in_bytes, &out_packets, &out_bytes); if(n == 2) return true; @@ -158,40 +158,54 @@ static int cmpu64(uint64_t a, uint64_t b) { 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; + int result; + switch(sortmode) { case 1: if(cumulative) - return -cmpu64(na->in_packets, nb->in_packets) ?: na->i - nb->i; + result = -cmpu64(na->in_packets, nb->in_packets); else - return -cmpfloat(na->in_packets_rate, nb->in_packets_rate) ?: na->i - nb->i; + result = -cmpfloat(na->in_packets_rate, nb->in_packets_rate); + break; case 2: if(cumulative) - return -cmpu64(na->in_bytes, nb->in_bytes) ?: na->i - nb->i; + result = -cmpu64(na->in_bytes, nb->in_bytes); else - return -cmpfloat(na->in_bytes_rate, nb->in_bytes_rate) ?: na->i - nb->i; + result = -cmpfloat(na->in_bytes_rate, nb->in_bytes_rate); + break; case 3: if(cumulative) - return -cmpu64(na->out_packets, nb->out_packets) ?: na->i - nb->i; + result = -cmpu64(na->out_packets, nb->out_packets); else - return -cmpfloat(na->out_packets_rate, nb->out_packets_rate) ?: na->i - nb->i; + result = -cmpfloat(na->out_packets_rate, nb->out_packets_rate); + break; case 4: if(cumulative) - return -cmpu64(na->out_bytes, nb->out_bytes) ?: na->i - nb->i; + result = -cmpu64(na->out_bytes, nb->out_bytes); else - return -cmpfloat(na->out_bytes_rate, nb->out_bytes_rate) ?: na->i - nb->i; + result = -cmpfloat(na->out_bytes_rate, nb->out_bytes_rate); + break; case 5: if(cumulative) - return -cmpu64(na->in_packets + na->out_packets, nb->in_packets + nb->out_packets) ?: na->i - nb->i; + result = -cmpu64(na->in_packets + na->out_packets, nb->in_packets + nb->out_packets); else - return -cmpfloat(na->in_packets_rate + na->out_packets_rate, nb->in_packets_rate + nb->out_packets_rate) ?: na->i - nb->i; + result = -cmpfloat(na->in_packets_rate + na->out_packets_rate, nb->in_packets_rate + nb->out_packets_rate); + break; case 6: if(cumulative) - return -cmpu64(na->in_bytes + na->out_bytes, nb->in_bytes + nb->out_bytes) ?: na->i - nb->i; + result = -cmpu64(na->in_bytes + na->out_bytes, nb->in_bytes + nb->out_bytes); else - return -cmpfloat(na->in_bytes_rate + na->out_bytes_rate, nb->in_bytes_rate + nb->out_bytes_rate) ?: na->i - nb->i; + result = -cmpfloat(na->in_bytes_rate + na->out_bytes_rate, nb->in_bytes_rate + nb->out_bytes_rate); + break; default: - return strcmp(na->name, nb->name) ?: na->i - nb->i; + result = strcmp(na->name, nb->name); + break; } + + if(result) + return result; + else + return na->i - nb->i; } static void redraw(void) { diff --git a/src/uml_device.c b/src/uml_device.c index 57d4843..68f4cd2 100644 --- a/src/uml_device.c +++ b/src/uml_device.c @@ -1,7 +1,7 @@ /* device.c -- UML network socket Copyright (C) 2002-2005 Ivo Timmermans, - 2002-2013 Guus Sliepen + 2002-2017 Guus Sliepen 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 @@ -228,7 +228,7 @@ static bool read_packet(vpn_packet_t *packet) { return false; } - if(connect(write_fd, &request.sock, sizeof request.sock) < 0) { + if(connect(write_fd, (struct sockkadr *)&request.sock, sizeof request.sock) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind write %s: %s", device_info, strerror(errno)); event_exit(); return false; diff --git a/src/upnp.c b/src/upnp.c index abd2f92..3bfc770 100644 --- a/src/upnp.c +++ b/src/upnp.c @@ -57,7 +57,7 @@ static struct UPNPDev *upnp_discover(int delay, int *error) { #elif MINIUPNPC_API_VERSION <= 14 - return upnpDiscover(delay, NULL NULL, false, false, 2, error); + return upnpDiscover(delay, NULL, NULL, false, false, 2, error); #else diff --git a/systemd/Makefile.in b/systemd/Makefile.in index 44e6bb2..f66a54e 100644 --- a/systemd/Makefile.in +++ b/systemd/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/systemd/tinc@.service b/systemd/tinc@.service index 78ef25b..d1f711d 100644 --- a/systemd/tinc@.service +++ b/systemd/tinc@.service @@ -11,6 +11,7 @@ Type=simple WorkingDirectory=/etc/tinc/%i ExecStart=/usr/sbin/tincd -n %i -D ExecReload=/usr/sbin/tinc -n %i reload +KillMode=mixed Restart=on-failure RestartSec=5 TimeoutStopSec=5 diff --git a/test/Makefile.am b/test/Makefile.am index df8e2c3..98f4a3b 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -4,9 +4,11 @@ TESTS = \ executables.test \ import-export.test \ invite-join.test \ + invite-offline.test \ invite-tinc-up.test \ ns-ping.test \ ping.test \ + scripts.test \ sptps-basic.test \ variables.test diff --git a/test/Makefile.in b/test/Makefile.in index 0dbe653..e5aadf2 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -477,9 +477,11 @@ TESTS = \ executables.test \ import-export.test \ invite-join.test \ + invite-offline.test \ invite-tinc-up.test \ ns-ping.test \ ping.test \ + scripts.test \ sptps-basic.test \ variables.test diff --git a/test/executables.test b/test/executables.test index 35dd2bc..801de58 100755 --- a/test/executables.test +++ b/test/executables.test @@ -5,4 +5,6 @@ # Just test whether the executables work $tincd --help $tinc --help -$sptps_test --help +if [ -e $sptps_test ]; then + $sptps_test --help +fi diff --git a/test/invite-join.test b/test/invite-join.test index c1bd1b8..28de83c 100755 --- a/test/invite-join.test +++ b/test/invite-join.test @@ -17,8 +17,6 @@ EOF # Generate an invitation and let another node join the VPN -sleep 1 - $tinc $c1 invite bar | $tinc $c2 join # Test equivalence of host config files diff --git a/test/invite-offline.test b/test/invite-offline.test new file mode 100755 index 0000000..b435493 --- /dev/null +++ b/test/invite-offline.test @@ -0,0 +1,50 @@ +#!/bin/sh + +. ./testlib.sh + +# Initialize one node + +$tinc $c1 < + Copyright (C) 2013-2017 Guus Sliepen 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 @@ -19,6 +19,8 @@ #include "../src/system.h" +#include "../src/ethernet.h" + uint8_t mymac[6] = {6, 5, 5, 6, 5, 5}; static ssize_t do_arp(uint8_t *buf, ssize_t len, struct sockaddr_in *in) { @@ -152,7 +154,7 @@ int main(int argc, char *argv[]) { #endif default: - fprintf(stderr, "Multicast for address family %hx unsupported\n", ai->ai_family); + fprintf(stderr, "Multicast for address family %x unsupported\n", ai->ai_family); return 1; } diff --git a/test/scripts.test b/test/scripts.test new file mode 100755 index 0000000..3b3f274 --- /dev/null +++ b/test/scripts.test @@ -0,0 +1,112 @@ +#!/bin/sh + +. ./testlib.sh + +# Initialize server node + +$tinc $c1 <$d1/$script << EOF +#!/bin/sh +echo $script \$NETNAME,\$NAME,\$DEVICE,\$IFACE,\$NODE,\$REMOTEADDRESS,\$REMOTEPORT,\$SUBNET,\$WEIGHT,\$INVITATION_FILE,\$INVITATION_URL,\$DEBUG >>$OUT +EOF +chmod u+x $d1/$script +done + +# Start server node + +$tinc -n netname $c1 start $r1 + +echo foo-started >>$OUT + +# Invite client node + +url=`$tinc -n netname2 $c1 invite bar` +file=`cd $d1/invitations; ls | grep -v ed25519_key.priv` +echo bar-invited >>$OUT +$tinc -n netname3 $c2 join $url +echo bar-joined >>$OUT + +# Start and stop client node + +$tinc $c2 << EOF +set DeviceType dummy +set Port 32760 +add Subnet 10.0.0.2 +add Subnet fec0::/64#5 +start $r2 +EOF + +sleep 1 + +echo bar-started >>$OUT + +$tinc $c1 debug 4 +$tinc $c2 stop + +sleep 1 + +echo bar-stopped >>$OUT + +$tinc $c1 debug 5 +$tinc $c2 start $r2 + +sleep 1 + +echo bar-started >>$OUT + +# Stop server node + +$tinc $c1 stop +sleep 1 +$tinc $c2 stop + +# Check if the script output is what is expected + +cat >$OUT.expected << EOF +tinc-up netname,foo,dummy,,,,,,,,,5 +subnet-up netname,foo,dummy,,foo,,,10.0.0.1,,,,5 +subnet-up netname,foo,dummy,,foo,,,fec0::/64,,,,5 +foo-started +invitation-created netname2,foo,,,bar,,,,,$d1/invitations/$file,$url, +bar-invited +invitation-accepted netname,foo,dummy,,bar,127.0.0.1,,,,,,5 +bar-joined +host-up netname,foo,dummy,,bar,127.0.0.1,32760,,,,,5 +hosts/bar-up netname,foo,dummy,,bar,127.0.0.1,32760,,,,,5 +subnet-up netname,foo,dummy,,bar,127.0.0.1,32760,10.0.0.2,,,,5 +subnet-up netname,foo,dummy,,bar,127.0.0.1,32760,fec0::/64,5,,,5 +bar-started +host-down netname,foo,dummy,,bar,127.0.0.1,32760,,,,,4 +hosts/bar-down netname,foo,dummy,,bar,127.0.0.1,32760,,,,,4 +subnet-down netname,foo,dummy,,bar,127.0.0.1,32760,10.0.0.2,,,,4 +subnet-down netname,foo,dummy,,bar,127.0.0.1,32760,fec0::/64,5,,,4 +bar-stopped +host-up netname,foo,dummy,,bar,127.0.0.1,32760,,,,,5 +hosts/bar-up netname,foo,dummy,,bar,127.0.0.1,32760,,,,,5 +subnet-up netname,foo,dummy,,bar,127.0.0.1,32760,10.0.0.2,,,,5 +subnet-up netname,foo,dummy,,bar,127.0.0.1,32760,fec0::/64,5,,,5 +bar-started +host-down netname,foo,dummy,,bar,127.0.0.1,32760,,,,,5 +hosts/bar-down netname,foo,dummy,,bar,127.0.0.1,32760,,,,,5 +subnet-down netname,foo,dummy,,bar,127.0.0.1,32760,10.0.0.2,,,,5 +subnet-down netname,foo,dummy,,bar,127.0.0.1,32760,fec0::/64,5,,,5 +subnet-down netname,foo,dummy,,foo,,,10.0.0.1,,,,5 +subnet-down netname,foo,dummy,,foo,,,fec0::/64,,,,5 +tinc-down netname,foo,dummy,,,,,,,,,5 +EOF + +cmp $OUT $OUT.expected diff --git a/test/sptps-basic.test b/test/sptps-basic.test index 644a31e..9f86c8c 100755 --- a/test/sptps-basic.test +++ b/test/sptps-basic.test @@ -2,6 +2,10 @@ . ./testlib.sh +# Skip this test if we did not compile sptps_test + +test -e $sptps_test || exit 77 + # Generate keys mkdir -p $d1 @@ -11,18 +15,18 @@ $sptps_keypair $d1/client.priv $d1/client.pub # Test transfer of a simple file. -(sleep 1; $sptps_test -q $d1/client.priv $d1/server.pub localhost 32750 <../README) & -$sptps_test $d1/server.priv $d1/client.pub 32750 >$d1/out1 +(sleep 1; $sptps_test -4 -q $d1/client.priv $d1/server.pub localhost 32750 <../README) & +$sptps_test -4 $d1/server.priv $d1/client.pub 32750 >$d1/out1 cmp $d1/out1 ../README -$sptps_test -q $d1/server.priv $d1/client.pub 32750 <../NEWS & +$sptps_test -4 -q $d1/server.priv $d1/client.pub 32750 <../NEWS & sleep 1 -$sptps_test $d1/client.priv $d1/server.pub localhost 32750 > $d1/out2 +$sptps_test -4 $d1/client.priv $d1/server.pub localhost 32750 > $d1/out2 cmp $d1/out2 ../NEWS # Datagram mode -$sptps_test -dq $d1/server.priv $d1/client.pub 32750 <../COPYING & +$sptps_test -4 -dq $d1/server.priv $d1/client.pub 32750 <../COPYING & sleep 1 -sleep 1 | $sptps_test -dq $d1/client.priv $d1/server.pub localhost 32750 >$d1/out3 +sleep 1 | $sptps_test -4 -dq $d1/client.priv $d1/server.pub localhost 32750 >$d1/out3 cmp $d1/out3 ../COPYING diff --git a/test/testlib.sh b/test/testlib.sh index 3103335..75b60a7 100644 --- a/test/testlib.sh +++ b/test/testlib.sh @@ -9,18 +9,10 @@ sptps_keypair=../src/sptps_keypair # Test directories -case "$_" in - /*) - d1=$_.1 - d2=$_.2 - d3=$_.3 - ;; - *) - d1=$PWD/$_.1 - d2=$PWD/$_.2 - d3=$PWD/$_.3 - ;; -esac +scriptname=`basename $0` +d1=$PWD/$scriptname.1 +d2=$PWD/$scriptname.2 +d3=$PWD/$scriptname.3 # Default arguments for both tinc and tincd