Import Upstream version 1.1~pre15

This commit is contained in:
Guus Sliepen 2019-08-26 13:44:52 +02:00
parent 87cef22421
commit bc8ca65653
85 changed files with 1687 additions and 971 deletions

View File

@ -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

105
ChangeLog
View File

@ -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
------------------------------------------------------------------------

316
INSTALL
View File

@ -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 `<wchar.h>' 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 '<wchar.h>' 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.

View File

@ -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

25
NEWS
View File

@ -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.

6
README
View File

@ -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 <guus@tinc-vpn.org>, and others.
tinc is Copyright © 1998-2017 Ivo Timmermans, Guus Sliepen <guus@tinc-vpn.org>, 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

44
aclocal.m4 vendored
View File

@ -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,

28
config.guess vendored
View File

@ -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 <<EOF
$0: unable to guess system type
This script, last modified $timestamp, has failed to recognize
the operating system you are using. It is advised that you
download the most up to date version of the config scripts from
This script (version $timestamp), has failed to recognize the
operating system you are using. If your script is old, overwrite
config.guess and config.sub with the latest versions from:
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
and
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
If the version you run ($0) is already up to date, please
send the following data and any information you think might be
pertinent to <config-patches@gnu.org> 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

View File

@ -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. */

22
config.sub vendored
View File

@ -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*)

26
configure vendored
View File

@ -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 <openssl/evp.h>
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 <openssl/evp.h>
"
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\\"

View File

@ -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:

View File

@ -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,

Binary file not shown.

View File

@ -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 ,

View File

@ -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
<guus@tinc-vpn.org> and Wessel Dankers <wsl@tinc-vpn.org>.
Permission is granted to make and distribute verbatim copies of this
@ -888,6 +888,11 @@ DeviceType = <TYPE> (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 = <yes | no> (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 <ADDRESS>
If this variable is specified, local discovery packets are sent to
the given ADDRESS.
LogLevel = <LEVEL> (0)
This option controls the verbosity of the logging. See *note Debug
levels::.
Mode = <router|switch|hub> (router)
This option selects the way packets are routed to other daemons.
@ -1039,6 +1044,9 @@ Mode = <router|switch|hub> (router)
every packet will be broadcast to the other daemons while no
routing table is managed.
InvitationExpire = <SECONDS> (604800)
This option controls the time invitations are valid.
KeyExpire = <SECONDS> (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 = <low|normal|high>
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

View File

@ -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 <guus@@tinc-vpn.org> and
Wessel Dankers <wsl@@tinc-vpn.org>.
@ -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 <guus@@tinc-vpn.org> and
Wessel Dankers <wsl@@tinc-vpn.org>.
@ -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|switch|hub> (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

View File

@ -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,

View File

@ -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 <openssl/evp.h>]
)

View File

@ -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 \

View File

@ -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

174
src/autoconnect.c Normal file
View File

@ -0,0 +1,174 @@
/*
autoconnect.c -- automatic connection establishment
Copyright (C) 2017 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "system.h"
#include "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();
}

25
src/autoconnect.h Normal file
View File

@ -0,0 +1,25 @@
/*
autoconnect.h -- header for autoconnect.c
Copyright (C) 2017 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __TINC_AUTOCONNECT_H__
#define __TINC_AUTOCONNECT_H__
extern void do_autoconnect(void);
#endif

View File

@ -1,7 +1,7 @@
/*
device.c -- Interaction BSD tun/tap device
Copyright (C) 2001-2005 Ivo Timmermans,
2001-2016 Guus Sliepen <guus@tinc-vpn.org>
2001-2017 Guus Sliepen <guus@tinc-vpn.org>
2009 Grzegorz Dymarek <gregd72002@googlemail.com>
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))

View File

@ -1,6 +1,6 @@
/*
cipher.h -- header file cipher.c
Copyright (C) 2007-2013 Guus Sliepen <guus@tinc-vpn.org>
Copyright (C) 2007-2016 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -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__));

View File

@ -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 */

View File

@ -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;

View File

@ -1,6 +1,6 @@
/*
digest.h -- header file digest.c
Copyright (C) 2007-2013 Guus Sliepen <guus@tinc-vpn.org>
Copyright (C) 2007-2016 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -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__));

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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];

View File

@ -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

123
src/fd_device.c Normal file
View File

@ -0,0 +1,123 @@
/*
fd_device.c -- Interaction with Android tun fd
Copyright (C) 2001-2005 Ivo Timmermans,
2001-2016 Guus Sliepen <guus@tinc-vpn.org>
2009 Grzegorz Dymarek <gregd72002@googlemail.com>
2016 Pacien TRAN-GIRARD <pacien@pacien.net>
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,
};

View File

@ -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) {

View File

@ -1,6 +1,6 @@
/*
graph.c -- graph algorithms
Copyright (C) 2001-2013 Guus Sliepen <guus@tinc-vpn.org>,
Copyright (C) 2001-2017 Guus Sliepen <guus@tinc-vpn.org>,
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);

View File

@ -1,6 +1,6 @@
/*
ifconfig.c -- Generate platform specific interface configuration commands
Copyright (C) 2016 Guus Sliepen <guus@tinc-vpn.org>
Copyright (C) 2016-2017 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -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
}

View File

@ -1,6 +1,6 @@
/*
info.c -- Show information about a node, subnet or address
Copyright (C) 2012-2013 Guus Sliepen <guus@tinc-vpn.org>
Copyright (C) 2012-2017 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -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;

View File

@ -1,6 +1,6 @@
/*
invitation.c -- Create and accept invitations
Copyright (C) 2013-2015 Guus Sliepen <guus@tinc-vpn.org>
Copyright (C) 2013-2017 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -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;

View File

@ -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;
}

View File

@ -1,6 +1,6 @@
/*
logger.c -- logging code
Copyright (C) 2004-2015 Guus Sliepen <guus@tinc-vpn.org>
Copyright (C) 2004-2017 Guus Sliepen <guus@tinc-vpn.org>
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;

View File

@ -1,7 +1,7 @@
/*
logger.h -- header file for logger.c
Copyright (C) 1998-2005 Ivo Timmermans
2000-2012 Guus Sliepen <guus@tinc-vpn.org>
2000-2017 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -67,7 +67,7 @@ enum {
#include <stdbool.h>
extern debug_t debug_level;
extern int debug_level;
extern bool logcontrol;
extern int umbilical;
extern void openlogger(const char *, logmode_t);

View File

@ -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) {

View File

@ -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;

View File

@ -1,7 +1,7 @@
/*
names.c -- generate commonly used (file)names
Copyright (C) 1998-2005 Ivo Timmermans
2000-2015 Guus Sliepen <guus@tinc-vpn.org>
2000-2017 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -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;
}

View File

@ -1,7 +1,7 @@
/*
names.h -- header for names.c
Copyright (C) 1998-2005 Ivo Timmermans
2000-2015 Guus Sliepen <guus@tinc-vpn.org>
2000-2017 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -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;

107
src/net.c
View File

@ -1,7 +1,7 @@
/*
net.c -- most of the network code
Copyright (C) 1998-2005 Ivo Timmermans,
2000-2015 Guus Sliepen <guus@tinc-vpn.org>
2000-2017 Guus Sliepen <guus@tinc-vpn.org>
2006 Scott Lamb <slamb@slamb.org>
2011 Loïc Grenié <loic.grenie@gmail.com>
@ -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});
}

View File

@ -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;

View File

@ -1,7 +1,7 @@
/*
net_packet.c -- Handles in- and outgoing VPN packets
Copyright (C) 1998-2005 Ivo Timmermans,
2000-2016 Guus Sliepen <guus@tinc-vpn.org>
2000-2017 Guus Sliepen <guus@tinc-vpn.org>
2010 Timothy Redaelli <timothy@redaelli.eu>
2010 Brandon Black <blblack@gmail.com>
@ -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();
}
}
}

View File

@ -1,7 +1,7 @@
/*
net_setup.c -- Setup.
Copyright (C) 1998-2005 Ivo Timmermans,
2000-2016 Guus Sliepen <guus@tinc-vpn.org>
2000-2017 Guus Sliepen <guus@tinc-vpn.org>
2006 Scott Lamb <slamb@slamb.org>
2010 Brandon Black <blblack@gmail.com>
@ -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);

View File

@ -1,7 +1,7 @@
/*
net_socket.c -- Handle various kinds of sockets.
Copyright (C) 1998-2005 Ivo Timmermans,
2000-2016 Guus Sliepen <guus@tinc-vpn.org>
2000-2017 Guus Sliepen <guus@tinc-vpn.org>
2006 Scott Lamb <slamb@slamb.org>
2009 Florian Forster <octo@verplant.org>
@ -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);

View File

@ -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,

View File

@ -1,6 +1,6 @@
/*
cipher.c -- Symmetric block cipher handling
Copyright (C) 2007-2013 Guus Sliepen <guus@tinc-vpn.org>
Copyright (C) 2007-2017 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -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;
}

View File

@ -1,6 +1,6 @@
/*
digest.c -- Digest handling
Copyright (C) 2007-2013 Guus Sliepen <guus@tinc-vpn.org>
Copyright (C) 2007-2016 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -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);

View File

@ -1,7 +1,7 @@
/*
protocol.h -- header for protocol.c
Copyright (C) 1999-2005 Ivo Timmermans,
2000-2013 Guus Sliepen <guus@tinc-vpn.org>
2000-2017 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -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.

View File

@ -1,7 +1,7 @@
/*
protocol_auth.c -- handle the meta-protocol, authentication
Copyright (C) 1999-2005 Ivo Timmermans,
2000-2014 Guus Sliepen <guus@tinc-vpn.org>
2000-2017 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -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;

View File

@ -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)

View File

@ -1,7 +1,7 @@
/*
protocol_key.c -- handle the meta-protocol, key exchange
Copyright (C) 1999-2005 Ivo Timmermans,
2000-2014 Guus Sliepen <guus@tinc-vpn.org>
2000-2017 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -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);

View File

@ -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. */

View File

@ -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

View File

@ -1,7 +1,7 @@
/*
script.c -- call an external script
Copyright (C) 1999-2005 Ivo Timmermans,
2000-2015 Guus Sliepen <guus@tinc-vpn.org>
2000-2017 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -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

View File

@ -1,7 +1,7 @@
/*
script.h -- header file for script.c
Copyright (C) 1999-2005 Ivo Timmermans,
2000-2013 Guus Sliepen <guus@tinc-vpn.org>
2000-2017 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -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__ */

View File

@ -24,6 +24,7 @@
#include <sys/stropts.h>
#include <sys/sockio.h>
#include <stropts.h>
#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;

View File

@ -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;

View File

@ -1,6 +1,6 @@
/*
subnet.c -- handle subnet lookups and lists
Copyright (C) 2000-2013 Guus Sliepen <guus@tinc-vpn.org>,
Copyright (C) 2000-2017 Guus Sliepen <guus@tinc-vpn.org>,
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) {

View File

@ -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;

View File

@ -1,6 +1,6 @@
/*
tincctl.c -- Controlling a running tincd
Copyright (C) 2007-2016 Guus Sliepen <guus@tinc-vpn.org>
Copyright (C) 2007-2017 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -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);
}

View File

@ -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!");

View File

@ -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) {

View File

@ -1,7 +1,7 @@
/*
device.c -- UML network socket
Copyright (C) 2002-2005 Ivo Timmermans,
2002-2013 Guus Sliepen <guus@tinc-vpn.org>
2002-2017 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -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;

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

50
test/invite-offline.test Executable file
View File

@ -0,0 +1,50 @@
#!/bin/sh
. ./testlib.sh
# Initialize one node
$tinc $c1 <<EOF
init foo
set DeviceType dummy
set Mode switch
set Broadcast no
del Port
set Address localhost
set Port 32758
EOF
# Generate an invitation offline and let another node join the VPN
invitation=`$tinc $c1 invite bar`
$tinc $c1 start $r1
$tinc $c2 join $invitation
# Test equivalence of host config files
cmp $d1/hosts/foo $d2/hosts/foo
test "`grep ^Ed25519PublicKey $d1/hosts/bar`" = "`grep ^Ed25519PublicKey $d2/hosts/bar`"
# Test Mode, Broadcast and ConnectTo statements
test `$tinc $c2 get Mode` = switch
test `$tinc $c2 get Broadcast` = no
test `$tinc $c2 get ConnectTo` = foo
# Check whether the new node can join the VPN
$tinc $c2 << EOF
set DeviceType dummy
set Port 0
start $r2
EOF
sleep 1
test `$tinc $c1 dump reachable nodes | wc -l` = 2
test `$tinc $c2 dump reachable nodes | wc -l` = 2
$tinc $c2 stop
$tinc $c1 stop

View File

@ -8,7 +8,7 @@ $tinc $c1 <<EOF
init foo
set DeviceType dummy
set Address localhost
set Port 32751
set Port 32756
start $r1
EOF

View File

@ -13,7 +13,7 @@ $tinc $c1 <<EOF
init foo
set Mode switch
set Interface ping.test1
set Port 32573
set Port 32577
set Address localhost
EOF

View File

@ -1,6 +1,6 @@
/*
pong.c -- ICMP echo reply generator
Copyright (C) 2013 Guus Sliepen <guus@tinc-vpn.org>
Copyright (C) 2013-2017 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -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;
}

112
test/scripts.test Executable file
View File

@ -0,0 +1,112 @@
#!/bin/sh
. ./testlib.sh
# Initialize server node
$tinc $c1 <<EOF
init foo
set DeviceType dummy
set Port 32759
set Address 127.0.0.1
add Subnet 10.0.0.1
add Subnet fec0::/64
EOF
# Set up scripts
OUT=$d1/scripts.out
rm -f $OUT
for script in tinc-up tinc-down host-up host-down subnet-up subnet-down hosts/foo-up hosts/foo-down hosts/bar-up hosts/bar-down invitation-created invitation-accepted; do
cat >$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

View File

@ -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

View File

@ -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