Import Upstream version 1.1~pre17

This commit is contained in:
Guus Sliepen 2019-08-26 13:44:53 +02:00
parent bc8ca65653
commit b511a112e6
216 changed files with 43313 additions and 18448 deletions

View file

@ -1,4 +1,4 @@
Copyright (C) 1998-2017 Ivo Timmermans, Guus Sliepen and others.
Copyright (C) 1998-2018 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

25548
ChangeLog

File diff suppressed because it is too large Load diff

View file

@ -2,12 +2,14 @@
AUTOMAKE_OPTIONS = gnu
SUBDIRS = src doc gui test systemd
SUBDIRS = src doc test systemd
ACLOCAL_AMFLAGS = -I m4
EXTRA_DIST = COPYING.README README.android
@CODE_COVERAGE_RULES@
# If git describe works, force autoconf to run in order to make sure we have the
# current version number from git in the resulting configure script.
configure-version:
@ -33,3 +35,6 @@ release:
echo "Please edit the NEWS file now..."
/usr/bin/editor $(srcdir)/NEWS
$(MAKE) dist
astyle:
astyle --options=.astylerc -nQ src/*.[ch] src/*/*.[ch]

View file

@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.15.1 from Makefile.am.
# Makefile.in generated by automake 1.16.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2017 Free Software Foundation, Inc.
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -94,6 +94,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
$(top_srcdir)/m4/ax_cflags_warn_all.m4 \
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
$(top_srcdir)/m4/ax_check_link_flag.m4 \
$(top_srcdir)/m4/ax_code_coverage.m4 \
$(top_srcdir)/m4/ax_require_defined.m4 \
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \
$(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \
@ -143,7 +144,7 @@ am__recursive_targets = \
$(RECURSIVE_CLEAN_TARGETS) \
$(am__extra_recursive_targets)
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
cscope distdir dist dist-all distcheck
cscope distdir distdir-am dist dist-all distcheck
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
$(LISP)config.h.in
# Read a list of newline-separated strings from the standard input,
@ -221,6 +222,12 @@ AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@
CODE_COVERAGE_CPPFLAGS = @CODE_COVERAGE_CPPFLAGS@
CODE_COVERAGE_CXXFLAGS = @CODE_COVERAGE_CXXFLAGS@
CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@
CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@
CODE_COVERAGE_LIBS = @CODE_COVERAGE_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CURSES_LIBS = @CURSES_LIBS@
@ -232,16 +239,18 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GCOV = @GCOV@
GENHTML = @GENHTML@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LCOV = @LCOV@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MINIUPNPC_LIBS = @MINIUPNPC_LIBS@
@ -256,6 +265,7 @@ PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
READLINE_LIBS = @READLINE_LIBS@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
@ -313,7 +323,7 @@ top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = gnu
SUBDIRS = src doc gui test systemd
SUBDIRS = src doc test systemd
ACLOCAL_AMFLAGS = -I m4
EXTRA_DIST = COPYING.README README.android
all: config.h
@ -341,8 +351,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
echo ' $(SHELL) ./config.status'; \
$(SHELL) ./config.status;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@ -475,7 +485,10 @@ distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
distdir: $(DISTFILES)
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
$(am__remove_distdir)
test -d "$(distdir)" || mkdir "$(distdir)"
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
@ -788,6 +801,8 @@ uninstall-am:
.PRECIOUS: Makefile
@CODE_COVERAGE_RULES@
# If git describe works, force autoconf to run in order to make sure we have the
# current version number from git in the resulting configure script.
configure-version:
@ -814,6 +829,9 @@ release:
/usr/bin/editor $(srcdir)/NEWS
$(MAKE) dist
astyle:
astyle --options=.astylerc -nQ src/*.[ch] src/*/*.[ch]
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

38
NEWS
View file

@ -1,3 +1,35 @@
# Version 1.1pre17 October 8 2018
* Prevent oracle attacks in the legacy protocol (CVE-2018-16737,
CVE-2018-16738).
* Prevent a MITM from forcing a NULL cipher for UDP in the legacy protocol
(CVE-2018-16758).
* AutoConnect is now enabled by default.
* Per-node network traffic statistics are now shown in the output of "info" and
"dump nodes" commands.
Thanks to volth and Rafael Sadowski for their contributions to this version of
tinc.
# Version 1.1pre16 June 12 2018
* Fixed building with support for UML sockets.
* Documentation updates and spelling fixes.
* Support for MSS clamping of IP-in-IP packets.
* Fixed parsing of the -b flag.
* Added the ability to set a firemall mark on sockets on Linux.
* Minor improvements to the build system.
* Added a cache of recently seen addresses of peers.
* Add support for --runstatedir to the configure script.
* Fixed linking with libncurses on some distributions.
* Automatically disable PMTUDiscovery when TCPOnly is enabled.
* Fixed removing the tinc service on Windows in some situations.
* Fixed the TAP-Win32 device locking up after waking up from suspend.
Thanks to Todd C. Miller, Etienne Dechamps, Daniel Lublin,
Gjergji Ramku, Mike Sullivan and Oliver Freyermuth for their
contributions to this version of tinc.
# Version 1.1pre15 September 2 2017
* Detect when the machine is resuming from suspension or hibernation.
@ -12,7 +44,7 @@
* 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.
* Store invitation data after a successful 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.
@ -43,7 +75,7 @@ contributions to this version of tinc.
* Allow tinc to be compiled without LibreSSL or OpenSSL (this drops
compatibility with nodes running 1.0.x).
* Added a "fsck" command to check the configuration files for problems.
* Tinc "start" now checks whether the daemon really started succesfully, and
* Tinc "start" now checks whether the daemon really started successfully, and
displays error messages otherwise.
* Added systemd service files.
* Use the recvmmsg() function if available.
@ -378,7 +410,7 @@ their contributions to this version of tinc.
* Improved default settings of tun and tap devices on BSD platforms.
* Make IPv6 sockets bind only to IPv6 on Linux.
* Enable path MTU discovery by default.
* Fixed a memory leak that occured when connections were closed.
* Fixed a memory leak that occurred when connections were closed.
Thanks to Max Rijevski for his contributions to this version of tinc.

28
README
View file

@ -1,7 +1,7 @@
This is the README file for tinc version 1.1pre15. Installation
This is the README file for tinc version 1.1pre17. Installation
instructions may be found in the INSTALL file.
tinc is Copyright © 1998-2017 Ivo Timmermans, Guus Sliepen <guus@tinc-vpn.org>, and others.
tinc is Copyright © 1998-2018 Ivo Timmermans, Guus Sliepen <guus@tinc-vpn.org>, and others.
For a complete list of authors see the AUTHORS file.
@ -28,11 +28,25 @@ Security statement
This version uses an experimental and unfinished cryptographic protocol. Use it
at your own risk.
When connecting to nodes that use the legacy protocol used in tinc 1.0, be
aware that any security issues in tinc 1.0 will apply to tinc 1.1 as well. On
September 6th, 2018, Michael Yonly contacted us and provided proof-of-concept
code that allowed a remote attacker to create an authenticated, one-way
connection with a node using the legacy protocol, and also that there was a
possibility for a man-in-the-middle to force UDP packets from a node to be sent
in plaintext. The first issue was trivial to exploit on tinc versions prior to
1.0.30, but the changes in 1.0.30 to mitigate the Sweet32 attack made this
weakness much harder to exploit. These issues have been fixed in tinc 1.0.35
and tinc 1.1pre17. The new protocol in the tinc 1.1 branch is not susceptible
to these issues. However, be aware that SPTPS is only used between nodes
running tinc 1.1pre* or later, and in a VPN with nodes running different
versions, the security might only be as good as that of the oldest version.
Compatibility
-------------
Version 1.1pre15 is compatible with 1.0pre8, 1.0 and later, but not with older
Version 1.1pre17 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
@ -50,9 +64,9 @@ ensure you have the latest stable versions of all the required libraries:
The following libraries are used by default, but can be disabled if necessary:
- zlib (http://www.zlib.net/)
- zlib (https://zlib.net/)
- LZO (https://www.oberhumer.com/opensource/lzo/)
- ncurses (http://invisible-island.net/ncurses/)
- ncurses (https://invisible-island.net/ncurses/)
- readline (https://cnswww.cns.cwru.edu/php/chet/readline/rltop.html)
@ -68,8 +82,8 @@ be forwarded by intermediate nodes.
Tinc 1.1 support two protocols. The first is a legacy protocol that provides
backwards compatibility with tinc 1.0 nodes, and which by default uses 2048 bit
RSA keys for authentication, and encrypts traffic using Blowfish in CBC mode
and HMAC-SHA1. The second is a new protocol which uses Curve25519 keys for
RSA keys for authentication, and encrypts traffic using AES256 in CBC mode
and HMAC-SHA256. The second is a new protocol which uses Curve25519 keys for
authentication, and encrypts traffic using Chacha20-Poly1305, and provides
forward secrecy.

18
THANKS
View file

@ -5,9 +5,12 @@ We would like to thank the following people for their contributions to tinc:
* Alexis Hildebrandt
* Allesandro Gatti
* Andreas van Cranenburgh
* Andrew Hahn
* Anthony G. Basile
* Armijn Hemel
* Armin Fisslthaler
* Aron Cowan
* Ashish Bajaj
* Baptiste Jonglez
* Borg
* Brandon Black
@ -19,35 +22,41 @@ We would like to thank the following people for their contributions to tinc:
* Delf Eldkraft
* Dennis Joachimsthaler
* dnk
* Élie Bouttier
* Enrique Zanardi
* Erik Tews
* Etienne Dechamps
* Florent Clairambault
* Florian Forster
* Florian Klink
* Florian Weik
* Flynn Marquardt
* Franz Pletz
* Gary Kessler and Claudia Gonzalez
* Grzegorz Dymarek
* Gusariev Oleksandr
* Hans Bayle
* Harvest
* Ivo Smits
* Ivo van Dong
* James Cook
* James MacLean
* Jamie Briggs
* Jason Harper
* Jason Livesay
* Jasper Krijgsman
* Jelle de Jong
* Jeroen Domburg
* Jeroen Ubbink
* Jerome Etienne
* Jo-Philipp Wich
* Jochen Voss
* Jo-Philipp Wich
* Julien Muchembled
* Lavrans Laading
* Loïc Dachary
* Loïc Grenié
* Lubomír Bulej
* luckyhacky
* LunarShaddow
* Mads Kiilerich
* Marc A. Lehmann
@ -63,18 +72,22 @@ We would like to thank the following people for their contributions to tinc:
* Menno Smits
* Mesar Hameed
* Michael Tokarev
* Michael Yonli
* Miles Nordin
* Nathan Stratton Treadway
* Murat Donmez
* Nathan Stratton Treadway
* Nick Hibma
* Nick Patavalis
* Paul Littlefield
* Philipp Babel
* Pierre Emeriaud
* Pierre-Olivier Mercier
* Rafael Sadowski
* Rafał Leśniak
* Rhosyn Celyn
* Robert van der Meulen
* Rumko
* Ryan Miller
* Sam Bryan
* Samuel Thibault
* Saverio Proto
@ -92,6 +105,7 @@ We would like to thank the following people for their contributions to tinc:
* Ulrich Seifert
* Vil Brekin
* Vittorio Gambaletta
* Wendy Willard
* Wessel Dankers
* William A. Kennington III
* William McArthur

188
aclocal.m4 vendored
View file

@ -1,6 +1,6 @@
# generated automatically by aclocal 1.15.1 -*- Autoconf -*-
# generated automatically by aclocal 1.16.1 -*- Autoconf -*-
# Copyright (C) 1996-2017 Free Software Foundation, Inc.
# Copyright (C) 1996-2018 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-2017 Free Software Foundation, Inc.
# Copyright (C) 2002-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -32,10 +32,10 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.])
# generated from the m4 files accompanying Automake X.Y.
# (This private macro should not be called outside this file.)
AC_DEFUN([AM_AUTOMAKE_VERSION],
[am__api_version='1.15'
[am__api_version='1.16'
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.1], [],
m4_if([$1], [1.16.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.1])dnl
[AM_AUTOMAKE_VERSION([1.16.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-2017 Free Software Foundation, Inc.
# Copyright (C) 2001-2018 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-2017 Free Software Foundation, Inc.
# Copyright (C) 1997-2018 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-2017 Free Software Foundation, Inc.
# Copyright (C) 1999-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -332,13 +332,12 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
# Generate code to set up dependency tracking. -*- Autoconf -*-
# Copyright (C) 1999-2017 Free Software Foundation, Inc.
# Copyright (C) 1999-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# _AM_OUTPUT_DEPENDENCY_COMMANDS
# ------------------------------
AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
@ -346,49 +345,41 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
# Older Autoconf quotes --file arguments for eval, but not when files
# are listed without --file. Let's play safe and only enable the eval
# if we detect the quoting.
case $CONFIG_FILES in
*\'*) eval set x "$CONFIG_FILES" ;;
*) set x $CONFIG_FILES ;;
esac
# TODO: see whether this extra hack can be removed once we start
# requiring Autoconf 2.70 or later.
AS_CASE([$CONFIG_FILES],
[*\'*], [eval set x "$CONFIG_FILES"],
[*], [set x $CONFIG_FILES])
shift
for mf
# Used to flag and report bootstrapping failures.
am_rc=0
for am_mf
do
# Strip MF so we end up with the name of the file.
mf=`echo "$mf" | sed -e 's/:.*$//'`
# Check whether this is an Automake generated Makefile or not.
# We used to match only the files named 'Makefile.in', but
# some people rename them; so instead we look at the file content.
# Grep'ing the first line is not enough: some people post-process
# each Makefile.in and add a new line on top of each file to say so.
# Grep'ing the whole file is not good either: AIX grep has a line
am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'`
# Check whether this is an Automake generated Makefile which includes
# dependency-tracking related rules and includes.
# Grep'ing the whole file directly is not great: AIX grep has a line
# limit of 2048, but all sed's we know have understand at least 4000.
if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
dirpart=`AS_DIRNAME("$mf")`
else
continue
sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \
|| continue
am_dirpart=`AS_DIRNAME(["$am_mf"])`
am_filepart=`AS_BASENAME(["$am_mf"])`
AM_RUN_LOG([cd "$am_dirpart" \
&& sed -e '/# am--include-marker/d' "$am_filepart" \
| $MAKE -f - am--depfiles]) || am_rc=$?
done
if test $am_rc -ne 0; then
AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments
for automatic dependency tracking. Try re-running configure with the
'--disable-dependency-tracking' option to at least be able to build
the package (albeit without support for automatic dependency tracking).])
fi
# Extract the definition of DEPDIR, am__include, and am__quote
# from the Makefile without running 'make'.
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
test -z "$DEPDIR" && continue
am__include=`sed -n 's/^am__include = //p' < "$mf"`
test -z "$am__include" && continue
am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
# Find all dependency output files, they are included files with
# $(DEPDIR) in their names. We invoke sed twice because it is the
# simplest approach to changing $(DEPDIR) to its actual value in the
# expansion.
for file in `sed -n "
s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
# Make sure the directory exists.
test -f "$dirpart/$file" && continue
fdir=`AS_DIRNAME(["$file"])`
AS_MKDIR_P([$dirpart/$fdir])
# echo "creating $dirpart/$file"
echo '# dummy' > "$dirpart/$file"
done
done
AS_UNSET([am_dirpart])
AS_UNSET([am_filepart])
AS_UNSET([am_mf])
AS_UNSET([am_rc])
rm -f conftest-deps.mk
}
])# _AM_OUTPUT_DEPENDENCY_COMMANDS
@ -397,18 +388,17 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
# -----------------------------
# This macro should only be invoked once -- use via AC_REQUIRE.
#
# This code is only required when automatic dependency tracking
# is enabled. FIXME. This creates each '.P' file that we will
# need in order to bootstrap the dependency handling code.
# This code is only required when automatic dependency tracking is enabled.
# This creates each '.Po' and '.Plo' makefile fragment that we'll need in
# order to bootstrap the dependency handling code.
AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
[AC_CONFIG_COMMANDS([depfiles],
[test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
[AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
])
[AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])])
# Do all the work for Automake. -*- Autoconf -*-
# Copyright (C) 1996-2017 Free Software Foundation, Inc.
# Copyright (C) 1996-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -495,8 +485,8 @@ AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
AC_REQUIRE([AC_PROG_MKDIR_P])dnl
# For better backward compatibility. To be removed once Automake 1.9.x
# dies out for good. For more background, see:
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
# We need awk for the "check" target (and possibly the TAP driver). The
# system "awk" is bad on some platforms.
@ -563,7 +553,7 @@ END
Aborting the configuration process, to ensure you take notice of the issue.
You can download and install GNU coreutils to get an 'rm' implementation
that behaves properly: <http://www.gnu.org/software/coreutils/>.
that behaves properly: <https://www.gnu.org/software/coreutils/>.
If you want to complete the configuration process using your problematic
'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
@ -605,7 +595,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-2017 Free Software Foundation, Inc.
# Copyright (C) 2001-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -626,7 +616,7 @@ if test x"${install_sh+set}" != xset; then
fi
AC_SUBST([install_sh])])
# Copyright (C) 2003-2017 Free Software Foundation, Inc.
# Copyright (C) 2003-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -647,7 +637,7 @@ AC_SUBST([am__leading_dot])])
# Check to see how 'make' treats includes. -*- Autoconf -*-
# Copyright (C) 2001-2017 Free Software Foundation, Inc.
# Copyright (C) 2001-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -655,49 +645,42 @@ AC_SUBST([am__leading_dot])])
# AM_MAKE_INCLUDE()
# -----------------
# Check to see how make treats includes.
# Check whether make has an 'include' directive that can support all
# the idioms we need for our automatic dependency tracking code.
AC_DEFUN([AM_MAKE_INCLUDE],
[am_make=${MAKE-make}
cat > confinc << 'END'
[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive])
cat > confinc.mk << 'END'
am__doit:
@echo this is the am__doit target
@echo this is the am__doit target >confinc.out
.PHONY: am__doit
END
# If we don't find an include directive, just comment out the code.
AC_MSG_CHECKING([for style of include used by $am_make])
am__include="#"
am__quote=
_am_result=none
# First try GNU make style include.
echo "include confinc" > confmf
# Ignore all kinds of additional output from 'make'.
case `$am_make -s -f confmf 2> /dev/null` in #(
*the\ am__doit\ target*)
am__include=include
am__quote=
_am_result=GNU
;;
esac
# Now try BSD make style include.
if test "$am__include" = "#"; then
echo '.include "confinc"' > confmf
case `$am_make -s -f confmf 2> /dev/null` in #(
*the\ am__doit\ target*)
am__include=.include
am__quote="\""
_am_result=BSD
;;
esac
# BSD make does it like this.
echo '.include "confinc.mk" # ignored' > confmf.BSD
# Other make implementations (GNU, Solaris 10, AIX) do it like this.
echo 'include confinc.mk # ignored' > confmf.GNU
_am_result=no
for s in GNU BSD; do
AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out])
AS_CASE([$?:`cat confinc.out 2>/dev/null`],
['0:this is the am__doit target'],
[AS_CASE([$s],
[BSD], [am__include='.include' am__quote='"'],
[am__include='include' am__quote=''])])
if test "$am__include" != "#"; then
_am_result="yes ($s style)"
break
fi
AC_SUBST([am__include])
AC_SUBST([am__quote])
AC_MSG_RESULT([$_am_result])
rm -f confinc confmf
])
done
rm -f confinc.* confmf.*
AC_MSG_RESULT([${_am_result}])
AC_SUBST([am__include])])
AC_SUBST([am__quote])])
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
# Copyright (C) 1997-2017 Free Software Foundation, Inc.
# Copyright (C) 1997-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -736,7 +719,7 @@ fi
# Helper functions for option handling. -*- Autoconf -*-
# Copyright (C) 2001-2017 Free Software Foundation, Inc.
# Copyright (C) 2001-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -765,7 +748,7 @@ AC_DEFUN([_AM_SET_OPTIONS],
AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
# Copyright (C) 1999-2017 Free Software Foundation, Inc.
# Copyright (C) 1999-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -812,7 +795,7 @@ AC_LANG_POP([C])])
# For backward compatibility.
AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
# Copyright (C) 2001-2017 Free Software Foundation, Inc.
# Copyright (C) 2001-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -831,7 +814,7 @@ AC_DEFUN([AM_RUN_LOG],
# Check to make sure that the build environment is sane. -*- Autoconf -*-
# Copyright (C) 1996-2017 Free Software Foundation, Inc.
# Copyright (C) 1996-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -912,7 +895,7 @@ AC_CONFIG_COMMANDS_PRE(
rm -f conftest.file
])
# Copyright (C) 2009-2017 Free Software Foundation, Inc.
# Copyright (C) 2009-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -972,7 +955,7 @@ AC_SUBST([AM_BACKSLASH])dnl
_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
])
# Copyright (C) 2001-2017 Free Software Foundation, Inc.
# Copyright (C) 2001-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -1000,7 +983,7 @@ fi
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])
# Copyright (C) 2006-2017 Free Software Foundation, Inc.
# Copyright (C) 2006-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -1019,7 +1002,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# Check how to create a tarball. -*- Autoconf -*-
# Copyright (C) 2004-2017 Free Software Foundation, Inc.
# Copyright (C) 2004-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -1155,6 +1138,7 @@ m4_include([m4/ax_append_flag.m4])
m4_include([m4/ax_cflags_warn_all.m4])
m4_include([m4/ax_check_compile_flag.m4])
m4_include([m4/ax_check_link_flag.m4])
m4_include([m4/ax_code_coverage.m4])
m4_include([m4/ax_require_defined.m4])
m4_include([m4/curses.m4])
m4_include([m4/libgcrypt.m4])

13
compile
View file

@ -1,9 +1,9 @@
#! /bin/sh
# Wrapper for compilers which do not understand '-c -o'.
scriptversion=2012-10-14.11; # UTC
scriptversion=2018-03-07.03; # UTC
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
# Copyright (C) 1999-2018 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify
@ -17,7 +17,7 @@ scriptversion=2012-10-14.11; # UTC
# 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, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@ -255,7 +255,8 @@ EOF
echo "compile $scriptversion"
exit $?
;;
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \
icl | *[/\\]icl | icl.exe | *[/\\]icl.exe )
func_cl_wrapper "$@" # Doesn't return...
;;
esac
@ -339,9 +340,9 @@ exit $ret
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# eval: (add-hook 'before-save-hook '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:

572
config.guess vendored

File diff suppressed because it is too large Load diff

View file

@ -42,9 +42,13 @@
/* Darwin (MacOS/X) */
#undef HAVE_DARWIN
/* 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 `EVP_aes_256_cfb', and to 0 if
you don't. */
#undef HAVE_DECL_EVP_AES_256_CFB
/* 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 `res_init', and to 0 if you
don't. */
@ -83,9 +87,6 @@
/* FreeBSD */
#undef HAVE_FREEBSD
/* Define to 1 if you have the `ftime' function. */
#undef HAVE_FTIME
/* Define to 1 if you have the <gcrypt.h> header file. */
#undef HAVE_GCRYPT_H
@ -98,6 +99,9 @@
/* Define to 1 if you have the `gettimeofday' function. */
#undef HAVE_GETTIMEOFDAY
/* Define to 1 if you have the `HMAC_CTX_new' function. */
#undef HAVE_HMAC_CTX_NEW
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
@ -424,5 +428,8 @@
/* Defined if the __malloc__ attribute is not supported. */
#undef __malloc__
/* Defined if the __nonnull__ attribute is not supported. */
#undef __nonnull__
/* Defined if the __warn_unused_result__ attribute is not supported. */
#undef __warn_unused_result__

252
config.sub vendored
View file

@ -1,8 +1,8 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright 1992-2016 Free Software Foundation, Inc.
# Copyright 1992-2018 Free Software Foundation, Inc.
timestamp='2016-11-04'
timestamp='2018-02-22'
# 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
@ -15,7 +15,7 @@ timestamp='2016-11-04'
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
# along with this program; if not, see <https://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@ -33,7 +33,7 @@ timestamp='2016-11-04'
# Otherwise, we print the canonical config type on stdout and succeed.
# You can get the latest version of this script from:
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
# This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases
@ -57,7 +57,7 @@ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
Canonicalize a configuration name.
Operation modes:
Options:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
@ -67,7 +67,7 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
Copyright 1992-2016 Free Software Foundation, Inc.
Copyright 1992-2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@ -94,7 +94,7 @@ while test $# -gt 0 ; do
*local*)
# First pass through any local machine types.
echo $1
echo "$1"
exit ;;
* )
@ -112,7 +112,7 @@ esac
# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
@ -120,16 +120,16 @@ case $maybe_os in
kopensolaris*-gnu* | cloudabi*-eabi* | \
storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
android-linux)
os=-linux-android
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
;;
*)
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
if [ $basic_machine != $1 ]
then os=`echo $1 | sed 's/.*-/-/'`
basic_machine=`echo "$1" | sed 's/-[^-]*$//'`
if [ "$basic_machine" != "$1" ]
then os=`echo "$1" | sed 's/.*-/-/'`
else os=; fi
;;
esac
@ -178,44 +178,44 @@ case $os in
;;
-sco6)
os=-sco5v6
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;;
-sco5)
os=-sco3.2v5
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;;
-sco4)
os=-sco3.2v4
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;;
-sco3.2.[4-9]*)
os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;;
-sco3.2v[4-9]*)
# Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;;
-sco5v6*)
# Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;;
-sco*)
os=-sco3.2v2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;;
-udk*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;;
-isc)
os=-isc2.2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;;
-clix*)
basic_machine=clipper-intergraph
;;
-isc*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;;
-lynx*178)
os=-lynxos178
@ -227,10 +227,7 @@ case $os in
os=-lynxos
;;
-ptx*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
;;
-windowsnt*)
os=`echo $os | sed -e 's/windowsnt/winnt/'`
basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'`
;;
-psos*)
os=-psos
@ -263,7 +260,7 @@ case $basic_machine in
| fido | fr30 | frv | ft32 \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \
| i370 | i860 | i960 | ia64 \
| i370 | i860 | i960 | ia16 | ia64 \
| ip2k | iq2000 \
| k1om \
| le32 | le64 \
@ -299,7 +296,7 @@ case $basic_machine in
| nios | nios2 | nios2eb | nios2el \
| ns16k | ns32k \
| open8 | or1k | or1knd | or32 \
| pdp10 | pdp11 | pj | pjl \
| pdp10 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle \
| pru \
| pyramid \
@ -315,7 +312,7 @@ case $basic_machine in
| ubicom32 \
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
| visium \
| we32k \
| wasm32 \
| x86 | xc16x | xstormy16 | xtensa \
| z8k | z80)
basic_machine=$basic_machine-unknown
@ -336,7 +333,7 @@ case $basic_machine in
basic_machine=$basic_machine-unknown
os=-none
;;
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65)
;;
ms1)
basic_machine=mt-unknown
@ -365,7 +362,7 @@ case $basic_machine in
;;
# Object if more than one company name word.
*-*-*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
exit 1
;;
# Recognize the basic CPU types with company name.
@ -388,7 +385,7 @@ case $basic_machine in
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| hexagon-* \
| i*86-* | i860-* | i960-* | ia64-* \
| i*86-* | i860-* | i960-* | ia16-* | ia64-* \
| ip2k-* | iq2000-* \
| k1om-* \
| le32-* | le64-* \
@ -446,6 +443,7 @@ case $basic_machine in
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
| vax-* \
| visium-* \
| wasm32-* \
| we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* \
| xstormy16-* | xtensa*-* \
@ -459,7 +457,7 @@ case $basic_machine in
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
386bsd)
basic_machine=i386-unknown
basic_machine=i386-pc
os=-bsd
;;
3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
@ -493,7 +491,7 @@ case $basic_machine in
basic_machine=x86_64-pc
;;
amd64-*)
basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
amdahl)
basic_machine=580-amdahl
@ -538,7 +536,7 @@ case $basic_machine in
os=-linux
;;
blackfin-*)
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'`
os=-linux
;;
bluegene*)
@ -546,13 +544,13 @@ case $basic_machine in
os=-cnk
;;
c54x-*)
basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
c55x-*)
basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
c6x-*)
basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
c90)
basic_machine=c90-cray
@ -641,7 +639,7 @@ case $basic_machine in
basic_machine=rs6000-bull
os=-bosx
;;
dpx2* | dpx2*-bull)
dpx2*)
basic_machine=m68k-bull
os=-sysv3
;;
@ -650,7 +648,7 @@ case $basic_machine in
os=$os"spe"
;;
e500v[12]-*)
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
os=$os"spe"
;;
ebmon29k)
@ -742,9 +740,6 @@ case $basic_machine in
hp9k8[0-9][0-9] | hp8[0-9][0-9])
basic_machine=hppa1.0-hp
;;
hppa-next)
os=-nextstep3
;;
hppaosf)
basic_machine=hppa1.1-hp
os=-osf
@ -757,26 +752,26 @@ case $basic_machine in
basic_machine=i370-ibm
;;
i*86v32)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
os=-sysv32
;;
i*86v4*)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
os=-sysv4
;;
i*86v)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
os=-sysv
;;
i*86sol2)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
os=-solaris2
;;
i386mach)
basic_machine=i386-mach
os=-mach
;;
i386-vsta | vsta)
vsta)
basic_machine=i386-unknown
os=-vsta
;;
@ -795,19 +790,16 @@ case $basic_machine in
os=-sysv
;;
leon-*|leon[3-9]-*)
basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'`
;;
m68knommu)
basic_machine=m68k-unknown
os=-linux
;;
m68knommu-*)
basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'`
os=-linux
;;
m88k-omron*)
basic_machine=m88k-omron
;;
magnum | m3230)
basic_machine=mips-mips
os=-sysv
@ -839,10 +831,10 @@ case $basic_machine in
os=-mint
;;
mips3*-*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`
;;
mips3*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown
;;
monitor)
basic_machine=m68k-rom68k
@ -861,7 +853,7 @@ case $basic_machine in
os=-msdos
;;
ms1-*)
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'`
;;
msys)
basic_machine=i686-pc
@ -948,6 +940,12 @@ case $basic_machine in
nsr-tandem)
basic_machine=nsr-tandem
;;
nsv-tandem)
basic_machine=nsv-tandem
;;
nsx-tandem)
basic_machine=nsx-tandem
;;
op50n-* | op60c-*)
basic_machine=hppa1.1-oki
os=-proelf
@ -980,7 +978,7 @@ case $basic_machine in
os=-linux
;;
parisc-*)
basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'`
os=-linux
;;
pbd)
@ -996,7 +994,7 @@ case $basic_machine in
basic_machine=i386-pc
;;
pc98-*)
basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
pentium | p5 | k5 | k6 | nexgen | viac3)
basic_machine=i586-pc
@ -1011,16 +1009,16 @@ case $basic_machine in
basic_machine=i786-pc
;;
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
pentiumpro-* | p6-* | 6x86-* | athlon-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
pentium4-*)
basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
pn)
basic_machine=pn-gould
@ -1030,23 +1028,23 @@ case $basic_machine in
ppc | ppcbe) basic_machine=powerpc-unknown
;;
ppc-* | ppcbe-*)
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle)
basic_machine=powerpcle-unknown
;;
ppcle-* | powerpclittle-*)
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
ppc64) basic_machine=powerpc64-unknown
;;
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
ppc64le | powerpc64little)
basic_machine=powerpc64le-unknown
;;
ppc64le-* | powerpc64little-*)
basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
ps2)
basic_machine=i386-ibm
@ -1100,17 +1098,10 @@ case $basic_machine in
sequent)
basic_machine=i386-sequent
;;
sh)
basic_machine=sh-hitachi
os=-hms
;;
sh5el)
basic_machine=sh5le-unknown
;;
sh64)
basic_machine=sh64-unknown
;;
sparclite-wrs | simso-wrs)
simso-wrs)
basic_machine=sparclite-wrs
os=-vxworks
;;
@ -1129,7 +1120,7 @@ case $basic_machine in
os=-sysv4
;;
strongarm-* | thumb-*)
basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
sun2)
basic_machine=m68000-sun
@ -1251,6 +1242,9 @@ case $basic_machine in
basic_machine=hppa1.1-winbond
os=-proelf
;;
x64)
basic_machine=x86_64-pc
;;
xbox)
basic_machine=i686-pc
os=-mingw32
@ -1259,20 +1253,12 @@ case $basic_machine in
basic_machine=xps100-honeywell
;;
xscale-* | xscalee[bl]-*)
basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'`
;;
ymp)
basic_machine=ymp-cray
os=-unicos
;;
z8k-*-coff)
basic_machine=z8k-unknown
os=-sim
;;
z80-*-coff)
basic_machine=z80-unknown
os=-sim
;;
none)
basic_machine=none-none
os=-none
@ -1301,10 +1287,6 @@ case $basic_machine in
vax)
basic_machine=vax-dec
;;
pdp10)
# there are many clones, so DEC is not a safe bet
basic_machine=pdp10-unknown
;;
pdp11)
basic_machine=pdp11-dec
;;
@ -1314,9 +1296,6 @@ case $basic_machine in
sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown
;;
sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
basic_machine=sparc-sun
;;
cydra)
basic_machine=cydra-cydrome
;;
@ -1336,7 +1315,7 @@ case $basic_machine in
# Make sure to match an already-canonicalized machine name.
;;
*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
exit 1
;;
esac
@ -1344,10 +1323,10 @@ esac
# Here we canonicalize certain aliases for manufacturers.
case $basic_machine in
*-digital*)
basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'`
;;
*-commodore*)
basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'`
;;
*)
;;
@ -1358,8 +1337,8 @@ esac
if [ x"$os" != x"" ]
then
case $os in
# First match some system type aliases
# that might get confused with valid system types.
# First match some system type aliases that might get confused
# with valid system types.
# -solaris* is a basic system type, with this one exception.
-auroraux)
os=-auroraux
@ -1370,18 +1349,19 @@ case $os in
-solaris)
os=-solaris2
;;
-svr4*)
os=-sysv4
;;
-unixware*)
os=-sysv4.2uw
;;
-gnu/linux*)
os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
;;
# First accept the basic system types.
# es1800 is here to avoid being matched by es* (a different OS)
-es1800*)
os=-ose
;;
# Now accept the basic system types.
# The portable systems comes first.
# Each alternative MUST END IN A *, to match a version number.
# Each alternative MUST end in a * to match a version number.
# -sysv* is not here because it comes later, after sysvr4.
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
@ -1391,25 +1371,26 @@ case $os in
| -aos* | -aros* | -cloudabi* | -sortix* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
| -hiux* | -knetbsd* | -mirbsd* | -netbsd* \
| -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* | -cegcc* \
| -chorusos* | -chorusrdb* | -cegcc* | -glidix* \
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -morphos* | -superux* | -rtmk* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
| -onefs* | -tirtos* | -phoenix* | -fuchsia*)
| -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \
| -midnightbsd*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@ -1426,12 +1407,12 @@ case $os in
-nto*)
os=`echo $os | sed -e 's|nto|nto-qnx|'`
;;
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
| -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
-sim | -xray | -os68k* | -v88r* \
| -windows* | -osx | -abug | -netware* | -os9* \
| -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
;;
-mac*)
os=`echo $os | sed -e 's|mac|macos|'`
os=`echo "$os" | sed -e 's|mac|macos|'`
;;
-linux-dietlibc)
os=-linux-dietlibc
@ -1440,10 +1421,10 @@ case $os in
os=`echo $os | sed -e 's|linux|linux-gnu|'`
;;
-sunos5*)
os=`echo $os | sed -e 's|sunos5|solaris2|'`
os=`echo "$os" | sed -e 's|sunos5|solaris2|'`
;;
-sunos6*)
os=`echo $os | sed -e 's|sunos6|solaris3|'`
os=`echo "$os" | sed -e 's|sunos6|solaris3|'`
;;
-opened*)
os=-openedition
@ -1454,12 +1435,6 @@ case $os in
-wince*)
os=-wince
;;
-osfrose*)
os=-osfrose
;;
-osf*)
os=-osf
;;
-utek*)
os=-bsd
;;
@ -1506,7 +1481,7 @@ case $os in
-oss*)
os=-sysv3
;;
-svr4)
-svr4*)
os=-sysv4
;;
-svr3)
@ -1521,24 +1496,28 @@ case $os in
-ose*)
os=-ose
;;
-es1800*)
os=-ose
;;
-xenix)
os=-xenix
;;
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
os=-mint
;;
-aros*)
os=-aros
;;
-zvmoe)
os=-zvmoe
;;
-dicos*)
os=-dicos
;;
-pikeos*)
# Until real need of OS specific support for
# particular features comes up, bare metal
# configurations are quite functional.
case $basic_machine in
arm*)
os=-eabi
;;
*)
os=-elf
;;
esac
;;
-nacl*)
;;
-ios)
@ -1548,7 +1527,7 @@ case $os in
*)
# Get rid of the `-' at the beginning of $os.
os=`echo $os | sed 's/[^-]*-//'`
echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2
exit 1
;;
esac
@ -1638,12 +1617,12 @@ case $basic_machine in
sparc-* | *-sun)
os=-sunos4.1.1
;;
pru-*)
os=-elf
;;
*-be)
os=-beos
;;
*-haiku)
os=-haiku
;;
*-ibm)
os=-aix
;;
@ -1698,9 +1677,6 @@ case $basic_machine in
i370-*)
os=-mvs
;;
*-next)
os=-nextstep3
;;
*-gould)
os=-sysv
;;
@ -1810,15 +1786,15 @@ case $basic_machine in
vendor=stratus
;;
esac
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"`
;;
esac
echo $basic_machine$os
echo "$basic_machine$os"
exit
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# eval: (add-hook 'write-file-functions 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"

2422
configure vendored

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,10 @@
dnl Process this file with autoconf to produce a configure script.
origcflags="$CFLAGS"
AC_PREREQ(2.61)
AC_INIT([tinc], m4_esyscmd_s((git describe || echo UNKNOWN) | sed 's/release-//'))
AC_CONFIG_SRCDIR([src/tincd.c])
AC_GNU_SOURCE
AM_INIT_AUTOMAKE([std-options subdir-objects nostdinc silent-rules -Wall])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
@ -19,10 +20,12 @@ dnl Checks for programs.
AC_PROG_CC_C99
AC_PROG_CPP
AC_PROG_INSTALL
AC_PROG_LN_S
AM_PROG_CC_C_O
dnl Check whether to enable code coverage testing, and if so, clear the default CFLAGS.
AX_CODE_COVERAGE
AS_IF([test "x$enable_code_coverage" = "xyes" -a "x$origcflags" = "x"], [CFLAGS=""])
dnl Check and set OS
AC_CANONICAL_HOST
@ -117,7 +120,7 @@ AC_ARG_WITH(systemd,
[ systemd=false ]
)
AS_IF([test "x$with_systemd" = "xyes"], [systemd_path="/lib/systemd/system"],
AS_IF([test "x$with_systemd" = "xyes"], [systemd_path="\${libdir}/systemd/system"],
[AS_IF([test "x$with_systemd" = "xno"], [systemd=false])])
AC_SUBST(systemd_path, $systemd_path)
@ -178,6 +181,7 @@ AC_CHECK_HEADERS([netinet/tcp.h netinet/ip_icmp.h netinet/icmp6.h],
dnl Checks for typedefs, structures, and compiler characteristics.
tinc_ATTRIBUTE(__malloc__)
tinc_ATTRIBUTE(__nonnull__)
tinc_ATTRIBUTE(__warn_unused_result__)
AC_CHECK_TYPES([struct ether_header, struct arphdr, struct ether_arp, struct ip, struct icmp, struct ip6_hdr, struct icmp6_hdr, struct nd_neighbor_solicit, struct nd_opt_hdr], , ,
@ -186,7 +190,7 @@ AC_CHECK_TYPES([struct ether_header, struct arphdr, struct ether_arp, struct ip,
dnl Checks for library functions.
AC_TYPE_SIGNAL
AC_CHECK_FUNCS([asprintf daemon fchmod flock ftime fork gettimeofday mlockall putenv recvmmsg strsignal nanosleep unsetenv vsyslog devname fdevname],
AC_CHECK_FUNCS([asprintf daemon fchmod flock fork gettimeofday mlockall putenv recvmmsg strsignal nanosleep unsetenv vsyslog devname fdevname],
[], [], [#include "$srcdir/src/have.h"]
)
@ -257,6 +261,11 @@ AC_ARG_ENABLE(jumbograms,
]
)
AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile gui/Makefile test/Makefile systemd/Makefile])
dnl Ensure runstatedir is set if we are using a version of autoconf that does not support it
if test "x$runstatedir" = "x"; then
AC_SUBST([runstatedir], ['${localstatedir}/run'])
fi
AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile test/Makefile systemd/Makefile])
AC_OUTPUT

View file

@ -1,9 +1,9 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2016-01-11.22; # UTC
scriptversion=2018-03-07.03; # UTC
# Copyright (C) 1999-2017 Free Software Foundation, Inc.
# Copyright (C) 1999-2018 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
@ -16,7 +16,7 @@ scriptversion=2016-01-11.22; # UTC
# 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, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@ -783,7 +783,7 @@ exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"

View file

@ -1,23 +1,13 @@
## Process this file with automake to get Makefile.in
info_TEXINFOS = tinc.texi
tinc_TEXINFOS = tincinclude.texi
man_MANS = tincd.8 tinc.8 tinc.conf.5 tinc-gui.8
EXTRA_DIST = tincinclude.texi.in tincd.8.in tinc.8.in tinc.conf.5.in tinc-gui.8.in sample-config.tar.gz
EXTRA_DIST = tincinclude.texi.in tincd.8.in tinc.8.in tinc.conf.5.in tinc-gui.8.in sample-config
CLEANFILES = *.html tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi sample-config.tar.gz
# Use `ginstall' in the definition of man_MANS to avoid
# confusion with the `install' target. The install rule transforms `ginstall'
# to install before applying any user-specified name transformations.
transform = s/ginstall/install/; @program_transform_name@
# For additional rules usually of interest only to the maintainer,
# see GNUmakefile and Makefile.maint.
sample-config.tar.gz: sample-config
$(AM_V_GEN)GZIP=$(GZIP_ENV) $(AMTAR) chozf $@ --exclude .svn $<
CLEANFILES = *.html tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi
tincd.8.html: tincd.8
$(AM_V_GEN)w3mman2html $? > $@
@ -35,21 +25,20 @@ substitute = sed \
-e s,'@PACKAGE\@',"$(PACKAGE)",g \
-e s,'@VERSION\@',"$(VERSION)",g \
-e s,'@sysconfdir\@',"$(sysconfdir)",g \
-e s,'@runstatedir\@',"$(runstatedir)",g \
-e s,'@localstatedir\@',"$(localstatedir)",g
tincd.8: tincd.8.in
$(AM_V_GEN)$(substitute) $? > $@
tincd.8: $(srcdir)/tincd.8.in
$(AM_V_GEN)$(substitute) $(srcdir)/tincd.8.in > $@
tinc.8: tinc.8.in
$(AM_V_GEN)$(substitute) $? > $@
tinc.8: $(srcdir)/tinc.8.in
$(AM_V_GEN)$(substitute) $(srcdir)/tinc.8.in > $@
tinc-gui.8: tinc-gui.8.in
$(AM_V_GEN)$(substitute) $? > $@
tinc-gui.8: $(srcdir)/tinc-gui.8.in
$(AM_V_GEN)$(substitute) $(srcdir)/tinc-gui.8.in > $@
tinc.conf.5: tinc.conf.5.in
$(AM_V_GEN)$(substitute) $? > $@
tinc.conf.5: $(srcdir)/tinc.conf.5.in
$(AM_V_GEN)$(substitute) $(srcdir)/tinc.conf.5.in > $@
tincinclude.texi: tincinclude.texi.in
$(AM_V_GEN)$(substitute) $? > $@
tinc.texi: tincinclude.texi
tincinclude.texi: $(srcdir)/tincinclude.texi.in
$(AM_V_GEN)$(substitute) $(srcdir)/tincinclude.texi.in > $@

View file

@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.15.1 from Makefile.am.
# Makefile.in generated by automake 1.16.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2017 Free Software Foundation, Inc.
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -78,6 +78,7 @@ install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
@ -93,6 +94,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
$(top_srcdir)/m4/ax_cflags_warn_all.m4 \
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
$(top_srcdir)/m4/ax_check_link_flag.m4 \
$(top_srcdir)/m4/ax_code_coverage.m4 \
$(top_srcdir)/m4/ax_require_defined.m4 \
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \
$(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \
@ -198,13 +200,8 @@ man8dir = $(mandir)/man8
NROFF = nroff
MANS = $(man_MANS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
am__DIST_COMMON = $(srcdir)/Makefile.in texinfo.tex
am__DIST_COMMON = $(srcdir)/Makefile.in $(tinc_TEXINFOS) texinfo.tex
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
# Use `ginstall' in the definition of man_MANS to avoid
# confusion with the `install' target. The install rule transforms `ginstall'
# to install before applying any user-specified name transformations.
transform = s/ginstall/install/; @program_transform_name@
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
@ -215,6 +212,12 @@ AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@
CODE_COVERAGE_CPPFLAGS = @CODE_COVERAGE_CPPFLAGS@
CODE_COVERAGE_CXXFLAGS = @CODE_COVERAGE_CXXFLAGS@
CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@
CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@
CODE_COVERAGE_LIBS = @CODE_COVERAGE_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CURSES_LIBS = @CURSES_LIBS@
@ -226,16 +229,18 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GCOV = @GCOV@
GENHTML = @GENHTML@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LCOV = @LCOV@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MINIUPNPC_LIBS = @MINIUPNPC_LIBS@
@ -250,6 +255,7 @@ PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
READLINE_LIBS = @READLINE_LIBS@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
@ -307,13 +313,15 @@ top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
info_TEXINFOS = tinc.texi
tinc_TEXINFOS = tincinclude.texi
man_MANS = tincd.8 tinc.8 tinc.conf.5 tinc-gui.8
EXTRA_DIST = tincinclude.texi.in tincd.8.in tinc.8.in tinc.conf.5.in tinc-gui.8.in sample-config.tar.gz
CLEANFILES = *.html tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi sample-config.tar.gz
EXTRA_DIST = tincinclude.texi.in tincd.8.in tinc.8.in tinc.conf.5.in tinc-gui.8.in sample-config
CLEANFILES = *.html tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi
substitute = sed \
-e s,'@PACKAGE\@',"$(PACKAGE)",g \
-e s,'@VERSION\@',"$(VERSION)",g \
-e s,'@sysconfdir\@',"$(sysconfdir)",g \
-e s,'@runstatedir\@',"$(runstatedir)",g \
-e s,'@localstatedir\@',"$(localstatedir)",g
all: all-am
@ -337,8 +345,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@ -393,10 +401,10 @@ $(am__aclocal_m4_deps):
else \
rm -rf $(@:.html=.htp); exit 1; \
fi
$(srcdir)/tinc.info: tinc.texi
tinc.dvi: tinc.texi
tinc.pdf: tinc.texi
tinc.html: tinc.texi
$(srcdir)/tinc.info: tinc.texi $(tinc_TEXINFOS)
tinc.dvi: tinc.texi $(tinc_TEXINFOS)
tinc.pdf: tinc.texi $(tinc_TEXINFOS)
tinc.html: tinc.texi $(tinc_TEXINFOS)
.dvi.ps:
$(AM_V_DVIPS)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
$(DVIPS) $(AM_V_texinfo) -o $@ $<
@ -583,7 +591,10 @@ ctags CTAGS:
cscope cscopelist:
distdir: $(DISTFILES)
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
@ -835,12 +846,6 @@ uninstall-man: uninstall-man5 uninstall-man8
.PRECIOUS: Makefile
# For additional rules usually of interest only to the maintainer,
# see GNUmakefile and Makefile.maint.
sample-config.tar.gz: sample-config
$(AM_V_GEN)GZIP=$(GZIP_ENV) $(AMTAR) chozf $@ --exclude .svn $<
tincd.8.html: tincd.8
$(AM_V_GEN)w3mman2html $? > $@
@ -853,22 +858,20 @@ tinc-gui.8.html: tinc-gui.8
tinc.conf.5.html: tinc.conf.5
$(AM_V_GEN)w3mman2html $? > $@
tincd.8: tincd.8.in
$(AM_V_GEN)$(substitute) $? > $@
tincd.8: $(srcdir)/tincd.8.in
$(AM_V_GEN)$(substitute) $(srcdir)/tincd.8.in > $@
tinc.8: tinc.8.in
$(AM_V_GEN)$(substitute) $? > $@
tinc.8: $(srcdir)/tinc.8.in
$(AM_V_GEN)$(substitute) $(srcdir)/tinc.8.in > $@
tinc-gui.8: tinc-gui.8.in
$(AM_V_GEN)$(substitute) $? > $@
tinc-gui.8: $(srcdir)/tinc-gui.8.in
$(AM_V_GEN)$(substitute) $(srcdir)/tinc-gui.8.in > $@
tinc.conf.5: tinc.conf.5.in
$(AM_V_GEN)$(substitute) $? > $@
tinc.conf.5: $(srcdir)/tinc.conf.5.in
$(AM_V_GEN)$(substitute) $(srcdir)/tinc.conf.5.in > $@
tincinclude.texi: tincinclude.texi.in
$(AM_V_GEN)$(substitute) $? > $@
tinc.texi: tincinclude.texi
tincinclude.texi: $(srcdir)/tincinclude.texi.in
$(AM_V_GEN)$(substitute) $(srcdir)/tincinclude.texi.in > $@
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.

Binary file not shown.

View file

@ -0,0 +1,15 @@
# Sample host configuration file
# The real IP address of this tinc host. Can be used by other tinc hosts.
Address = 123.234.35.67
# Portnumber for incoming connections. Default is 655.
Port = 655
# Subnet on the virtual private network that is local for this host.
Subnet = 192.168.1.0/24
# The public key generated by `tincd -n example -K' is stored here
-----BEGIN RSA PUBLIC KEY-----
...
-----END RSA PUBLIC KEY-----

View file

@ -0,0 +1,16 @@
# Sample host configuration file
# This file was generated by host beta.
# The real IP address of this tinc host. Can be used by other tinc hosts.
Address = 123.45.67.189
# Portnumber for incoming connections. Default is 655.
Port = 6500
# Subnet on the virtual private network that is local for this host.
Subnet = 192.168.2.0/24
# The public key generated by `tincd -n example -K' is stored here
-----BEGIN RSA PUBLIC KEY-----
...
-----END RSA PUBLIC KEY-----

View file

@ -0,0 +1 @@
# Generate this file with `tincd -n example -K`

View file

@ -0,0 +1,4 @@
#!/bin/sh
# This file closes down the tap device.
ifconfig $INTERFACE down

11
doc/sample-config/tinc-up Normal file
View file

@ -0,0 +1,11 @@
#!/bin/sh
# This file sets up the tap device.
# It gives you the freedom to do anything you want with it.
# Use the correct name for the tap device:
# The environment variable $INTERFACE is set to the right name
# on most platforms, but if it doesn't work try to set it manually.
# Give it the right ip and netmask. Remember, the subnet of the
# tap device must be larger than that of the individual Subnets
# as defined in the host configuration file!
ifconfig $INTERFACE 192.168.1.1 netmask 255.255.0.0

View file

@ -0,0 +1,22 @@
# Sample tinc configuration file
# This is a comment.
# Spaces and tabs are eliminated.
# The = sign isn't strictly necessary any longer, though you may want
# to leave it in as it improves readability :)
# Variable names are treated case insensitive.
# The name of this tinc host. Required.
Name = alpha
# The internet host to connect with.
# Comment these out to make yourself a listen-only connection
# You must use the name of another tinc host.
# May be used multiple times for redundance.
ConnectTo = beta
# The tap device tinc will use.
# Default is /dev/tap0 for ethertap or FreeBSD,
# /dev/tun0 for Solaris and OpenBSD,
# and /dev/net/tun for Linux tun/tap device.
Device = /dev/net/tun

File diff suppressed because it is too large Load diff

View file

@ -30,7 +30,7 @@ Use the cookie from
.Ar FILENAME
to authenticate with a running tinc daemon.
If unspecified, the default is
.Pa @localstatedir@/run/tinc. Ns Ar NETNAME Ns Pa .pid.
.Pa @runstatedir@/tinc. Ns Ar NETNAME Ns Pa .pid.
.It Fl -help
Display short list of options.
.El

View file

@ -7,10 +7,11 @@
.Nd tinc VPN control
.Sh SYNOPSIS
.Nm
.Op Fl cn
.Op Fl bcn
.Op Fl -config Ns = Ns Ar DIR
.Op Fl -net Ns = Ns Ar NETNAME
.Op Fl -pidfile Ns = Ns Ar FILENAME
.Op Fl -batch
.Op Fl -force
.Op Fl -help
.Op Fl -version
@ -54,7 +55,9 @@ Use the cookie from
.Ar FILENAME
to authenticate with a running tinc daemon.
If unspecified, the default is
.Pa @localstatedir@/run/tinc. Ns Ar NETNAME Ns Pa .pid.
.Pa @runstatedir@/tinc. Ns Ar NETNAME Ns Pa .pid.
.It Fl b, -batch
Don't ask for anything (non-interactive mode).
.It Fl -force
Force some commands to work despite warnings.
.It Fl -help
@ -249,7 +252,7 @@ to allow a signature from any node whose public key is known.
If no
.Ar filename
is given, the file is read from standard input.
If the verification is succesful,
If the verification is successful,
a copy of the input with the signature removed is written to standard output,
and the exit code will be zero.
If the verification failed,

View file

@ -114,7 +114,7 @@ If
.Qq any
is selected, then depending on the operating system both IPv4 and IPv6 or just
IPv6 listening sockets will be created.
.It Va AutoConnect Li = yes | no Po no Pc Bq experimental
.It Va AutoConnect Li = yes | no Po yes
If set to yes,
.Nm tinc
will automatically set up meta connections to other nodes,
@ -177,7 +177,7 @@ line).
.Pp
If you don't specify a host with
.Va ConnectTo
and don't enable
and have disabled
.Va AutoConnect ,
.Nm tinc
won't try to connect to other daemons at all,
@ -242,7 +242,7 @@ Packets received for the local node are written to it.
Create a UNIX socket with the filename specified by
.Va Device ,
or
.Pa @localstatedir@/run/ Ns Ar NETNAME Ns Pa .umlsocket
.Pa @runstatedir@/ Ns Ar NETNAME Ns Pa .umlsocket
if not specified.
.Nm tinc
will wait for a User Mode Linux instance to connect to this socket.
@ -251,7 +251,7 @@ Uses the libvdeplug library to connect to a Virtual Distributed Ethernet switch,
using the UNIX socket specified by
.Va Device ,
or
.Pa @localstatedir@/run/vde.ctl
.Pa @runstatedir@/vde.ctl
if not specified.
.El
Also, in case tinc does not seem to correctly interpret packets received from the virtual network device,
@ -306,10 +306,16 @@ Incoming packets that are meant for another node are forwarded by tinc internall
.Pp
This is the default mode, and unless you really know you need another forwarding mode, don't change it.
.It kernel
Incoming packets are always sent to the TUN/TAP device, even if the packets are not for the local node.
Incoming packets using the legacy protocol are always sent to the TUN/TAP device,
even if the packets are not for the local node.
This is less efficient, but allows the kernel to apply its routing and firewall rules on them,
and can also help debugging.
Incoming packets using the SPTPS protocol are dropped, since they are end-to-end encrypted.
.El
.It Va FWMark Li = Ar value Po 0 Pc Bq experimental
When set to a non-zero value, all TCP and UDP sockets created by tinc will use the given value as the firewall mark.
This can be used for mark-based routing or for packet filtering.
This option is currently only supported on Linux.
.It Va Hostnames Li = yes | no Pq no
This option selects whether IP addresses (both real and on the VPN) should
be resolved. Since DNS lookups are blocking, it might affect tinc's
@ -786,7 +792,7 @@ 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.
After a successful 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.4.90 from tinc.texi.
This is tinc.info, produced by makeinfo version 6.5 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.1pre14-62-g958a751e, a
Virtual Private Network daemon.
This is the info manual for tinc version 1.1pre17, a Virtual Private
Network daemon.
Copyright (C) 1998-2017 Ivo Timmermans, Guus Sliepen
Copyright (C) 1998-2018 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
@ -285,7 +285,7 @@ File: tinc.info, Node: Libraries, Prev: Configuring the kernel, Up: Preparati
=============
Before you can configure or build tinc, you need to have the LibreSSL or
OpenSSL, zlib, lzo, curses and readline libraries installed on your
OpenSSL, zlib, LZO, curses and readline libraries installed on your
system. If you try to configure tinc without having them installed,
configure will give you an error message, and stop.
@ -293,7 +293,7 @@ configure will give you an error message, and stop.
* LibreSSL/OpenSSL::
* zlib::
* lzo::
* LZO::
* libcurses::
* libreadline::
@ -306,7 +306,7 @@ File: tinc.info, Node: LibreSSL/OpenSSL, Next: zlib, Up: Libraries
For all cryptography-related functions, tinc uses the functions provided
by the LibreSSL or the OpenSSL library.
If this library is not installed, you wil get an error when configuring
If this library is not installed, you will get an error when configuring
tinc for build. Support for running tinc with other cryptographic
libraries installed _may_ be added in the future.
@ -316,7 +316,7 @@ of this package.
If your operating system comes neither with LibreSSL or OpenSSL, you
have to install one manually. It is recommended that you get the latest
version of LibreSSL from <http://www.libressl.org/>. Instructions on
version of LibreSSL from <https://www.libressl.org/>. Instructions on
how to configure, build and install this package are included within the
package. Please make sure you build development and runtime libraries
(which is the default).
@ -357,7 +357,7 @@ present the following exemption:
Markus F.X.J. Oberhumer

File: tinc.info, Node: zlib, Next: lzo, Prev: LibreSSL/OpenSSL, Up: Libraries
File: tinc.info, Node: zlib, Next: LZO, Prev: LibreSSL/OpenSSL, Up: Libraries
2.2.2 zlib
----------
@ -365,7 +365,7 @@ File: tinc.info, Node: zlib, Next: lzo, Prev: LibreSSL/OpenSSL, Up: Librarie
For the optional compression of UDP packets, tinc uses the functions
provided by the zlib library.
If this library is not installed, you wil get an error when running the
If this library is not installed, you will get an error when running the
configure script. You can either install the zlib library, or disable
support for zlib compression by using the "-disable-zlib" option when
running the configure script. Note that if you disable support for
@ -377,19 +377,19 @@ available. Make sure you install the development AND runtime versions
of this package.
If you have to install zlib manually, you can get the source code from
<http://www.zlib.net/>. Instructions on how to configure, build and
<https://zlib.net/>. Instructions on how to configure, build and
install this package are included within the package. Please make sure
you build development and runtime libraries (which is the default).

File: tinc.info, Node: lzo, Next: libcurses, Prev: zlib, Up: Libraries
File: tinc.info, Node: LZO, Next: libcurses, Prev: zlib, Up: Libraries
2.2.3 lzo
2.2.3 LZO
---------
Another form of compression is offered using the LZO library.
If this library is not installed, you wil get an error when running the
If this library is not installed, you will get an error when running the
configure script. You can either install the LZO library, or disable
support for LZO compression by using the "-disable-lzo" option when
running the configure script. Note that if you disable support for LZO,
@ -400,29 +400,29 @@ You can use your operating system's package manager to install this if
available. Make sure you install the development AND runtime versions
of this package.
If you have to install lzo manually, you can get the source code from
If you have to install LZO manually, you can get the source code from
<https://www.oberhumer.com/opensource/lzo/>. Instructions on how to
configure, build and install this package are included within the
package. Please make sure you build development and runtime libraries
(which is the default).

File: tinc.info, Node: libcurses, Next: libreadline, Prev: lzo, Up: Libraries
File: tinc.info, Node: libcurses, Next: libreadline, Prev: LZO, Up: Libraries
2.2.4 libcurses
---------------
For the "tinc top" command, tinc requires a curses library.
If this library is not installed, you wil get an error when running the
If this library is not installed, you will get an error when running the
configure script. You can either install a suitable curses library, or
disable all functionality that depends on a curses library by using the
"-disable-curses" option when running the configure script.
There are several curses libraries. It is recommended that you install
"ncurses" (<http://invisible-island.net/ncurses/>), however other curses
libraries should also work. In particular, "PDCurses"
(<http://pdcurses.sourceforge.net/>) is recommended if you want to
"ncurses" (<https://invisible-island.net/ncurses/>), however other
curses libraries should also work. In particular, "PDCurses"
(<https://pdcurses.sourceforge.io/>) is recommended if you want to
compile tinc for Windows.
You can use your operating system's package manager to install this if
@ -438,7 +438,7 @@ File: tinc.info, Node: libreadline, Prev: libcurses, Up: Libraries
For the "tinc" command's shell functionality, tinc uses the readline
library.
If this library is not installed, you wil get an error when running the
If this library is not installed, you will get an error when running the
configure script. You can either install a suitable readline library,
or disable all functionality that depends on a readline library by using
the "-disable-readline" option when running the configure script.
@ -448,7 +448,7 @@ available. Make sure you install the development AND runtime versions
of this package.
If you have to install libreadline manually, you can get the source code
from <http://www.gnu.org/software/readline/>. Instructions on how to
from <https://www.gnu.org/software/readline/>. Instructions on how to
configure, build and install this package are included within the
package. Please make sure you build development and runtime libraries
(which is the default).
@ -625,7 +625,7 @@ Do you want to run tinc in router mode or switch mode? These questions
can only be answered by yourself, you will not find the answers in this
documentation. Make sure you have an adequate understanding of networks
in general. A good resource on networking is the Linux Network
Administrators Guide (http://www.tldp.org/LDP/nag2/).
Administrators Guide (https://www.tldp.org/LDP/nag2/).
If you have everything clearly pictured in your mind, proceed in the
following order: First, create the initial configuration files and
@ -651,7 +651,7 @@ assign a NETNAME to your VPN. It is not required if you only run one
tinc daemon, it doesn't even have to be the same on all the nodes of
your VPN, but it is recommended that you choose one anyway.
We will asume you use a netname throughout this document. This means
We will assume you use a netname throughout this document. This means
that you call tinc with the -n argument, which will specify the netname.
The effect of this option is that tinc will set its configuration root
@ -675,22 +675,17 @@ File: tinc.info, Node: How connections work, Next: Configuration files, Prev:
========================
When tinc starts up, it parses the command-line options and then reads
in the configuration file tinc.conf. If it sees one or more 'ConnectTo'
values pointing to other tinc daemons in that file, it will try to
connect to those other daemons. Whether this succeeds or not and
whether 'ConnectTo' is specified or not, tinc will listen for incoming
connection from other deamons. If you did specify a 'ConnectTo' value
and the other side is not responding, tinc will keep retrying. This
means that once started, tinc will stay running until you tell it to
stop, and failures to connect to other tinc daemons will not stop your
tinc daemon for trying again later. This means you don't have to
intervene if there are temporary network problems.
in the configuration file tinc.conf. It will then start listening for
incoming connection from other daemons, and will by default also
automatically try to connect to known peers. By default, tinc will try
to keep at least 3 working meta-connections alive at all times.
There is no real distinction between a server and a client in tinc. If
you wish, you can view a tinc daemon without a 'ConnectTo' value as a
server, and one which does specify such a value as a client. It does
not matter if two tinc daemons have a 'ConnectTo' value pointing to each
other however.
you wish, you can view a tinc daemon without a 'ConnectTo' statement in
tinc.conf and 'AutoConnect = no' as a server, and one which does have
one or more 'ConnectTo' statements or 'Autoconnect = yes' (which is the
default) as a client. It does not matter if two tinc daemons have a
'ConnectTo' value pointing to each other however.
Connections specified using 'ConnectTo' are so-called meta-connections.
Tinc daemons exchange information about all other daemon they know about
@ -712,7 +707,7 @@ might also prevent direct communication. In that case, VPN packets
between A and C will be forwarded by B.
In effect, all nodes in the VPN will be able to talk to each other, as
long as their is a path of meta-connections between them, and whenever
long as there is a path of meta-connections between them, and whenever
possible, two nodes will communicate with each other directly.

@ -725,8 +720,8 @@ The actual configuration of the daemon is done in the file
'/etc/tinc/NETNAME/tinc.conf' and at least one other file in the
directory '/etc/tinc/NETNAME/hosts/'.
An optionnal directory '/etc/tinc/NETNAME/conf.d' can be added from
which any .conf file will be read.
An optional directory '/etc/tinc/NETNAME/conf.d' can be added from which
any .conf file will be read.
These file consists of comments (lines started with a #) or assignments
in the form of
@ -771,7 +766,7 @@ AddressFamily = <ipv4|ipv6|any> (any)
system both IPv4 and IPv6 or just IPv6 listening sockets will be
created.
AutoConnect = <yes|no> (no) [experimental]
AutoConnect = <yes|no> (yes)
If set to yes, tinc will automatically set up meta connections to
other nodes, without requiring CONNECTTO variables.
@ -831,7 +826,7 @@ ConnectTo = <NAME>
names should be known to this tinc daemon (i.e., there should be a
host configuration file for the name on the ConnectTo line).
If you don't specify a host with ConnectTo and don't enable
If you don't specify a host with ConnectTo and have disabled
AutoConnect, tinc won't try to connect to other daemons at all, and
will instead just listen for incoming connections.
@ -966,10 +961,18 @@ Forwarding = <off|internal|kernel> (internal) [experimental]
another forwarding mode, don't change it.
kernel
Incoming packets are always sent to the TUN/TAP device, even
if the packets are not for the local node. This is less
efficient, but allows the kernel to apply its routing and
firewall rules on them, and can also help debugging.
Incoming packets using the legacy protocol are always sent to
the TUN/TAP device, even if the packets are not for the local
node. This is less efficient, but allows the kernel to apply
its routing and firewall rules on them, and can also help
debugging. Incoming packets using the SPTPS protocol are
dropped, since they are end-to-end encrypted.
FWMark = <VALUE> (0) [experimental]
When set to a non-zero value, all TCP and UDP sockets created by
tinc will use the given value as the firewall mark. This can be
used for mark-based routing or for packet filtering. This option
is currently only supported on Linux.
Hostnames = <yes|no> (no)
This option selects whether IP addresses (both real and on the VPN)
@ -1093,7 +1096,7 @@ PriorityInheritance = <yes|no> (no) [experimental]
PrivateKey = <KEY> [obsolete]
This is the RSA private key for tinc. However, for safety reasons
it is advised to store private keys of any kind in separate files.
This prevents accidental eavesdropping if you are editting the
This prevents accidental eavesdropping if you are editing the
configuration file.
PrivateKeyFile = <PATH> ('/etc/tinc/NETNAME/rsa_key.priv')
@ -1243,7 +1246,7 @@ ClampMSS = <yes|no> (yes)
Compression = <LEVEL> (0)
This option sets the level of compression used for UDP packets.
Possible values are 0 (off), 1 (fast zlib) and any integer up to 9
(best zlib), 10 (fast lzo) and 11 (best lzo).
(best zlib), 10 (fast LZO) and 11 (best LZO).
Digest = <DIGEST> (sha1)
The digest algorithm used to authenticate UDP packets using the
@ -1299,9 +1302,9 @@ PublicKeyFile = <PATH> [obsolete]
Subnet = <ADDRESS[/PREFIXLENGTH[#WEIGHT]]>
The subnet which this tinc daemon will serve. Tinc tries to look
up which other daemon it should send a packet to by searching the
appropiate subnet. If the packet matches a subnet, it will be sent
to the daemon who has this subnet in his host configuration file.
Multiple subnet lines can be specified for each daemon.
appropriate subnet. If the packet matches a subnet, it will be
sent to the daemon who has this subnet in his host configuration
file. Multiple subnet lines can be specified for each daemon.
Subnets can either be single MAC, IPv4 or IPv6 addresses, in which
case a subnet consisting of only that single address is assumed, or
@ -1513,26 +1516,14 @@ run:
tinc -n NETNAME add address foo.example.org
If you already know to which daemons your daemon should make
meta-connections, you should configure that now as well. Suppose you
want to connect to a daemon named "bar", run:
tinc -n NETNAME add connectto bar
Note that you specify the Name of the other daemon here, not an IP
address or hostname! When you start tinc, and it tries to make a
connection to "bar", it will look for a host configuration file named
'hosts/bar', and will read Address statements and public keys from that
file.
Step 2. Exchanging configuration files.
.......................................
If your daemon has a ConnectTo = bar statement in its 'tinc.conf' file,
or if bar has a ConnectTo your daemon, then you both need each other's
host configuration files. You should send 'hosts/NAME' to bar, and bar
should send you his file which you should move to 'hosts/bar'. If you
are on a UNIX platform, you can easily send an email containing the
In order for two tinc daemons to be able to connect to each other, they
each need the other's host configuration files. So if you want foo to
be able to connect with bar, You should send 'hosts/NAME' to bar, and
bar should send you his file which you should move to 'hosts/bar'. If
you are on a UNIX platform, you can easily send an email containing the
necessary information using the following command (assuming the owner of
bar has the email address bar@example.org):
@ -1552,10 +1543,9 @@ following command:
| ssh bar.example.org tinc -n NETNAME exchange \
| tinc -n NETNAME import
You should repeat this for all nodes you ConnectTo, or which ConnectTo
you. However, remember that you do not need to ConnectTo all nodes in
the VPN; it is only necessary to create one or a few meta-connections,
after the connections are made tinc will learn about all the other nodes
You can repeat this for a few other nodes as well. It is not necessary
to manually exchange host config files between all nodes; after the
initial connections are made tinc will learn about all the other nodes
in the VPN, and will automatically make other connections as necessary.

@ -1692,11 +1682,9 @@ In '/etc/tinc/company/tinc-up':
and in '/etc/tinc/company/tinc.conf':
Name = BranchB
ConnectTo = BranchA
Note here that the internal address (on eth0) doesn't have to be the
same as on the VPN interface. Also, ConnectTo is given so that this
node will always try to connect to BranchA.
same as on the VPN interface.
On all hosts, in '/etc/tinc/company/hosts/BranchB':
@ -1722,7 +1710,6 @@ In '/etc/tinc/company/tinc-up':
and in '/etc/tinc/company/tinc.conf':
Name = BranchC
ConnectTo = BranchA
C already has another daemon that runs on port 655, so they have to
reserve another port for tinc. It knows the portnumber it has to listen
@ -1753,7 +1740,6 @@ In '/etc/tinc/company/tinc-up':
and in '/etc/tinc/company/tinc.conf':
Name = BranchD
ConnectTo = BranchC
D will be connecting to C, which has a tincd running for this network on
port 2000. It knows the port number from the host configuration file.
@ -1861,6 +1847,9 @@ command line options.
facility. If FILE is omitted, the default is
'/var/log/tinc.NETNAME.log'.
'--pidfile=FILE'
Write PID to FILE instead of '/var/run/tinc.NETNAME.pid'.
'--bypass-security'
Disables encryption and authentication. Only useful for debugging.
@ -1871,12 +1860,16 @@ command line options.
chroot is performed after all the initialization is done, after
writing pid files and opening network sockets.
Note that this option alone does not do any good without -U/-user,
below.
This option is best used in combination with the -U/-user option
described below.
Note also that tinc can't run scripts anymore (such as tinc-down or
host-up), unless it's setup to be runnable inside chroot
environment.
You will need to ensure the chroot environment contains all the
files necessary for tinc to run correctly. Most importantly, for
tinc to be able to resolve hostnames inside the chroot environment,
you must copy '/etc/resolv.conf' into the chroot directory. If you
want to be able to run scripts other than 'tinc-up' in the chroot,
you must ensure the appropriate shell is also installed in the
chroot, along with all its dependencies.
This option is not supported on all platforms.
'-U, --user=USER'
@ -2150,6 +2143,9 @@ File: tinc.info, Node: tinc runtime options, Next: tinc environment variables,
daemon. If unspecified, the default is
'/var/run/tinc.NETNAME.pid'.
'-b, --batch'
Don't ask for anything (non-interactive mode).
'--force'
Force some commands to work despite warnings.
@ -2353,8 +2349,8 @@ File: tinc.info, Node: tinc commands, Next: tinc examples, Prev: tinc environ
NAME of the node must be given, or can be "." to check against the
local node's public key, or "*" to allow a signature from any node
whose public key is known. If no FILENAME is given, the file is
read from standard input. If the verification is succesful, a copy
of the input with the signature removed is written to standard
read from standard input. If the verification is successful, a
copy of the input with the signature removed is written to standard
output, and the exit code will be zero. If the verification
failed, nothing will be written to standard output, and the exit
code will be non-zero.
@ -2376,7 +2372,7 @@ Examples of changing the configuration using tinc:
tinc -n vpn init foo
tinc -n vpn add Subnet 192.168.1.0/24
tinc -n vpn add bar.Address bar.example.com
tinc -n vpn add ConnectTo bar
tinc -n vpn set Mode switch
tinc -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@example.com

@ -2400,7 +2396,7 @@ can be changed using the following keys:
<c>
Toggle between displaying current traffic rates (in packets and
bytes per second) and cummulative traffic (total packets and bytes
bytes per second) and cumulative traffic (total packets and bytes
since the tinc daemon started).
<n>
@ -2528,7 +2524,8 @@ invite' command looks like this:
The file is basically a concatenation of several host config blocks.
Each host config block starts with 'Name = ...'. Lines that look like
'#---#' are not important, it just makes it easier for humans to read
the file.
the file. However, the first line of an invitation file _must_ always
start with 'Name = ...'.
The first host config block is always the one representing the invitee.
So the first Name statement determines the name that the invitee will
@ -2582,7 +2579,7 @@ When an invitation is generated, the "invitation-created" script is
called (if it exists) right after the invitation file is written, but
before the URL has been written to stdout. This allows one to change
the invitation file automatically before the invitation URL is passed to
the invitee. Here is an example shell script that aproximately
the invitee. Here is an example shell script that approximately
recreates the default invitation file:
#!/bin/sh
@ -2684,8 +2681,7 @@ correct destination MAC address. In those modes every interface should
have a unique MAC address, so make sure they are not the same. Because
switch and hub modes rely on MAC addresses to function correctly, these
modes cannot be used on the following operating systems which don't have
a 'tap' style virtual network device: OpenBSD, NetBSD, Darwin and
Solaris.
a 'tap' style virtual network device: NetBSD, Darwin and Solaris.

File: tinc.info, Node: The meta-connection, Prev: The UDP tunnel, Up: The connection
@ -3189,14 +3185,29 @@ too short, and he doesn't like tinc's use of RSA during authentication.
We do not know of a security hole in the legacy protocol of tinc, but it
is not as strong as TLS or IPsec.
The Sweet32 attack affects versions of tinc prior to 1.0.30.
On September 6th, 2018, Michael Yonly contacted us and provided
proof-of-concept code that allowed a remote attacker to create an
authenticated, one-way connection with a node, and also that there was a
possibility for a man-in-the-middle to force UDP packets from a node to
be sent in plaintext. The first issue was trivial to exploit on tinc
versions prior to 1.0.30, but the changes in 1.0.30 to mitigate the
Sweet32 attack made this weakness much harder to exploit. These issues
have been fixed in tinc 1.0.35.
This version of tinc comes with an improved protocol, called Simple
Peer-to-Peer Security, which aims to be as strong as TLS with one of the
strongest cipher suites.
Peer-to-Peer Security (SPTPS), which aims to be as strong as TLS with
one of the strongest cipher suites. None of the above security issues
affected SPTPS. However, be aware that SPTPS is only used between nodes
running tinc 1.1pre* or later, and in a VPN with nodes running different
versions, the security might only be as good as that of the oldest
version.
Cryptography is a hard thing to get right. We cannot make any
guarantees. Time, review and feedback are the only things that can
prove the security of any cryptographic product. If you wish to review
tinc or give us feedback, you are stronly encouraged to do so.
tinc or give us feedback, you are strongly encouraged to do so.

File: tinc.info, Node: Platform specific information, Next: About us, Prev: Technical information, Up: Top
@ -3208,6 +3219,7 @@ File: tinc.info, Node: Platform specific information, Next: About us, Prev: T
* Interface configuration::
* Routes::
* Automatically starting tinc::

File: tinc.info, Node: Interface configuration, Next: Routes, Up: Platform specific information
@ -3246,11 +3258,6 @@ Solaris 'ifconfig' INTERFACE 'inet6 plumb up'
Darwin (MacOS/X) 'ifconfig' INTERFACE 'inet6' ADDRESS 'prefixlen' PREFIXLENGTH
Windows 'netsh interface ipv6 add address' INTERFACE 'static' ADDRESS/PREFIXLENGTH
On some platforms, when running tinc in switch mode, the VPN interface
must be set to tap mode with an ifconfig command:
OpenBSD 'ifconfig' INTERFACE 'link0'
On Linux, it is possible to create a persistent tun/tap interface which
will continue to exist even if tinc quit, although this is normally not
required. It can be useful to set up a tun/tap interface owned by a
@ -3260,7 +3267,7 @@ privileges at all.
Linux 'ip tuntap add dev' INTERFACE 'mode' TUN|TAP 'user' USERNAME

File: tinc.info, Node: Routes, Prev: Interface configuration, Up: Platform specific information
File: tinc.info, Node: Routes, Next: Automatically starting tinc, Prev: Interface configuration, Up: Platform specific information
9.2 Routes
==========
@ -3295,6 +3302,72 @@ Solaris 'route add -inet6' NETWORK_ADDRESS'/'PREFIXLENGTH LOCAL_ADDRE
Darwin (MacOS/X) ?
Windows 'netsh interface ipv6 add route' NETWORK ADDRESS/PREFIXLENGTH INTERFACE

File: tinc.info, Node: Automatically starting tinc, Prev: Routes, Up: Platform specific information
9.3 Automatically starting tinc
===============================
* Menu:
* Linux::
* Windows::
* Other platforms::

File: tinc.info, Node: Linux, Next: Windows, Up: Automatically starting tinc
9.3.1 Linux
-----------
There are many Linux distributions, and historically, many of them had
their own way of starting programs at boot time. Today, a number of
major Linux distributions have chosen to use systemd as their init
system. Tinc ships with systemd service files that allow you to start
and stop tinc using systemd. There are two service files:
'tinc.service' is used to globally enable or disable all tinc daemons
managed by systemd, and 'tinc@NETNAME.service' is used to enable or
disable specific tinc daemons. So if one has created a tinc network
with netname 'foo', then you have to run the following two commands to
ensure it is started at boot time:
systemctl enable tinc
systemctl enable tinc@foo
To start the tinc daemon immediately if it wasn't already running, use
the following command:
systemctl start tinc@foo
You can also use 'systemctl start tinc', this will start all tinc
daemons that are enabled. You can stop and disable tinc networks in the
same way.
If your system is not using systemd, then you have to look up your
distribution's way of starting tinc at boot time.

File: tinc.info, Node: Windows, Next: Other platforms, Prev: Linux, Up: Automatically starting tinc
9.3.2 Windows
-------------
On Windows, if tinc is started with the 'tinc start' command without
using the '-D' or '--no-detach' option, it will automatically register
itself as a service that is started at boot time. When tinc is stopped
using the 'tinc stop' command, it will also automatically unregister
itself. Once tinc is registered as a service, it is also possible to
stop and start tinc using the Windows Services Manager.

File: tinc.info, Node: Other platforms, Prev: Windows, Up: Automatically starting tinc
9.3.3 Other platforms
---------------------
On platforms other than the ones mentioned in the earlier sections, you
have to look up your platform's way of starting programs at boot time.

File: tinc.info, Node: About us, Next: Concept Index, Prev: Platform specific information, Up: Top
@ -3354,6 +3427,8 @@ Concept Index
* ANS_KEY: The meta-protocol. (line 63)
* AutoConnect: Main configuration variables.
(line 12)
* batch: tinc runtime options.
(line 18)
* binary package: Building and installing tinc.
(line 9)
* BindToAddress: Main configuration variables.
@ -3376,7 +3451,7 @@ Concept Index
* ClampMSS: Host configuration variables.
(line 22)
* client: How connections work.
(line 18)
(line 12)
* command line: Runtime options. (line 9)
* command line interface: Controlling tinc. (line 6)
* Compression: Host configuration variables.
@ -3422,7 +3497,7 @@ Concept Index
* exchange: tinc commands. (line 48)
* exchange-all: tinc commands. (line 51)
* exec: Main configuration variables.
(line 365)
(line 373)
* ExperimentalProtocol: Main configuration variables.
(line 185)
* export: tinc commands. (line 36)
@ -3433,38 +3508,40 @@ Concept Index
(line 192)
* frame type: The UDP tunnel. (line 6)
* fsck: tinc commands. (line 160)
* FWMark: Main configuration variables.
(line 214)
* generate-ed25519-keys: tinc commands. (line 86)
* generate-keys: tinc commands. (line 81)
* generate-rsa-keys: tinc commands. (line 89)
* get: tinc commands. (line 11)
* graph: tinc commands. (line 108)
* Hostnames: Main configuration variables.
(line 212)
(line 220)
* http: Main configuration variables.
(line 362)
(line 370)
* hub: Main configuration variables.
(line 280)
(line 288)
* ID: Legacy authentication protocol.
(line 6)
* Ifconfig: Invitation file format.
(line 35)
(line 36)
* import: tinc commands. (line 43)
* IndirectData: Host configuration variables.
(line 40)
* info: tinc commands. (line 120)
* init: tinc commands. (line 6)
* Interface: Main configuration variables.
(line 223)
(line 231)
* INTERFACE: Scripts. (line 75)
* InvitationExpire: Main configuration variables.
(line 285)
(line 293)
* 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 288)
(line 296)
* KEY_CHANGED: The meta-protocol. (line 63)
* legacy authentication protocol: Legacy authentication protocol.
(line 6)
@ -3474,31 +3551,31 @@ Concept Index
* LibreSSL: LibreSSL/OpenSSL. (line 6)
* license: LibreSSL/OpenSSL. (line 38)
* ListenAddress: Main configuration variables.
(line 231)
(line 239)
* LocalDiscovery: Main configuration variables.
(line 243)
(line 251)
* log: tinc commands. (line 130)
* LogLevel: Main configuration variables.
(line 254)
* lzo: lzo. (line 6)
(line 262)
* LZO: LZO. (line 6)
* MACExpire: Main configuration variables.
(line 294)
(line 302)
* MACLength: Host configuration variables.
(line 45)
* MaxConnectionBurst: Main configuration variables.
(line 299)
(line 307)
* meta-protocol: The meta-connection. (line 18)
* META_KEY: Legacy authentication protocol.
(line 6)
* Mode: Main configuration variables.
(line 258)
(line 266)
* MTUInfoInterval: Host configuration variables.
(line 60)
* multicast: Main configuration variables.
(line 118)
* multiple networks: Multiple networks. (line 6)
* Name: Main configuration variables.
(line 305)
(line 313)
* NAME: Scripts. (line 69)
* netmask: Network interfaces. (line 39)
* netname: Multiple networks. (line 6)
@ -3517,9 +3594,9 @@ Concept Index
* pid: tinc commands. (line 78)
* PING: The meta-protocol. (line 88)
* PingInterval: Main configuration variables.
(line 316)
(line 324)
* PingTimeout: Main configuration variables.
(line 320)
(line 328)
* platforms: Supported platforms. (line 6)
* PMTU: Host configuration variables.
(line 52)
@ -3530,17 +3607,17 @@ Concept Index
(line 65)
* port numbers: Other files. (line 17)
* PriorityInheritance: Main configuration variables.
(line 326)
(line 334)
* private: Virtual Private Networks.
(line 10)
* PrivateKey: Main configuration variables.
(line 331)
(line 339)
* PrivateKeyFile: Main configuration variables.
(line 337)
(line 345)
* ProcessPriority: Main configuration variables.
(line 342)
(line 350)
* Proxy: Main configuration variables.
(line 347)
(line 355)
* PublicKey: Host configuration variables.
(line 69)
* PublicKeyFile: Host configuration variables.
@ -3553,40 +3630,41 @@ Concept Index
* REMOTEADDRESS: Scripts. (line 84)
* REMOTEPORT: Scripts. (line 87)
* ReplayWindow: Main configuration variables.
(line 370)
(line 378)
* requirements: Libraries. (line 6)
* REQ_KEY: The meta-protocol. (line 63)
* restart: tinc commands. (line 70)
* retry: tinc commands. (line 135)
* Route: Invitation file format.
(line 51)
(line 52)
* router: Main configuration variables.
(line 261)
(line 269)
* runtime options: Runtime options. (line 9)
* scalability: tinc. (line 19)
* scripts: Scripts. (line 6)
* server: How connections work.
(line 18)
(line 12)
* set: tinc commands. (line 16)
* shell: Controlling tinc. (line 11)
* sign: tinc commands. (line 172)
* signals: Signals. (line 6)
* socks4: Main configuration variables.
(line 351)
(line 359)
* socks5: Main configuration variables.
(line 356)
(line 364)
* SPTPS: Simple Peer-to-Peer Security.
(line 6)
* start: tinc commands. (line 64)
* stop: tinc commands. (line 67)
* StrictSubnets: Main configuration variables.
(line 381)
(line 389)
* Subnet: Host configuration variables.
(line 84)
* SUBNET: Scripts. (line 91)
* SVPN: Security. (line 11)
* switch: Main configuration variables.
(line 269)
(line 277)
* systemd: Linux. (line 6)
* TCP: The meta-connection. (line 10)
* TCPonly: Host configuration variables.
(line 113)
@ -3602,36 +3680,36 @@ Concept Index
* tunifhead: Main configuration variables.
(line 158)
* TunnelServer: Main configuration variables.
(line 388)
(line 396)
* tunnohead: Main configuration variables.
(line 152)
* UDP: The UDP tunnel. (line 30)
* UDP <1>: Encryption of network packets.
(line 11)
* UDPDiscoveryInterval: Main configuration variables.
(line 408)
(line 416)
* UDPDiscoveryKeepaliveInterval: Main configuration variables.
(line 402)
(line 410)
* UDPDiscoveryTimeout: Main configuration variables.
(line 412)
(line 420)
* UDPDiscovey: Main configuration variables.
(line 395)
(line 403)
* UDPInfoInterval: Main configuration variables.
(line 417)
(line 425)
* UDPRcvBuf: Main configuration variables.
(line 421)
(line 429)
* UDPSndBuf: Main configuration variables.
(line 427)
(line 435)
* UML: Main configuration variables.
(line 134)
* Universal tun/tap: Configuration of Linux kernels.
(line 6)
* UPnP: Main configuration variables.
(line 433)
(line 441)
* UPnPDiscoverWait: Main configuration variables.
(line 444)
(line 452)
* UPnPRefreshPeriod: Main configuration variables.
(line 448)
(line 456)
* utun: Main configuration variables.
(line 165)
* VDE: Main configuration variables.
@ -3652,78 +3730,82 @@ Concept Index

Tag Table:
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
Node: Top808
Node: Introduction1144
Node: Virtual Private Networks1948
Node: tinc3660
Node: Supported platforms5173
Node: Preparations5870
Node: Configuring the kernel6126
Node: Configuration of Linux kernels6535
Node: Configuration of FreeBSD kernels7384
Node: Configuration of OpenBSD kernels7849
Node: Configuration of NetBSD kernels8206
Node: Configuration of Solaris kernels8608
Node: Configuration of Darwin (MacOS/X) kernels9270
Node: Configuration of Windows10083
Node: Libraries10622
Node: LibreSSL/OpenSSL11079
Node: zlib13607
Node: LZO14627
Node: libcurses15619
Node: libreadline16531
Node: Installation17470
Node: Building and installing tinc18374
Node: Darwin (MacOS/X) build environment19030
Node: Cygwin (Windows) build environment19589
Node: MinGW (Windows) build environment20174
Node: System files20762
Node: Device files21027
Node: Other files21440
Node: Configuration22053
Node: Configuration introduction22340
Node: Multiple networks23862
Node: How connections work25230
Node: Configuration files27494
Node: Main configuration variables29125
Node: Host configuration variables50523
Node: Scripts56595
Node: How to configure60495
Node: Network interfaces64406
Node: Example configuration66785
Node: Running tinc71726
Node: Runtime options72313
Node: Signals75581
Node: Debug levels76430
Node: Solving problems77366
Node: Error messages78792
Node: Sending bug reports83109
Node: Controlling tinc84056
Node: tinc runtime options84792
Node: tinc environment variables85608
Node: tinc commands85937
Node: tinc examples92796
Node: tinc top93356
Node: Invitations94940
Node: How invitations work95603
Node: Invitation file format97896
Node: Writing an invitation-created script100907
Node: Technical information101970
Node: The connection102200
Node: The UDP tunnel102512
Node: The meta-connection105548
Node: The meta-protocol107006
Node: Security111989
Node: Legacy authentication protocol113326
Node: Simple Peer-to-Peer Security117943
Node: Encryption of network packets123588
Node: Security issues126226
Node: Platform specific information128818
Node: Interface configuration129078
Node: Routes131348
Node: Automatically starting tinc133295
Node: Linux133518
Node: Windows134730
Node: Other platforms135274
Node: About us135556
Node: Contact information135733
Node: Authors136136
Node: Concept Index136540

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-2017 Ivo Timmermans,
Copyright @copyright{} 1998-2018 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-2017 Ivo Timmermans,
Copyright @copyright{} 1998-2018 Ivo Timmermans,
Guus Sliepen <guus@@tinc-vpn.org> and
Wessel Dankers <wsl@@tinc-vpn.org>.
@ -331,14 +331,14 @@ as explained in the rest of the documentation.
@cindex requirements
@cindex libraries
Before you can configure or build tinc, you need to have the LibreSSL or OpenSSL, zlib,
lzo, curses and readline libraries installed on your system. If you try to
LZO, curses and readline libraries installed on your system. If you try to
configure tinc without having them installed, configure will give you an error
message, and stop.
@menu
* LibreSSL/OpenSSL::
* zlib::
* lzo::
* LZO::
* libcurses::
* libreadline::
@end menu
@ -353,7 +353,7 @@ message, and stop.
For all cryptography-related functions, tinc uses the functions provided
by the LibreSSL or the OpenSSL library.
If this library is not installed, you wil get an error when configuring
If this library is not installed, you will get an error when configuring
tinc for build. Support for running tinc with other cryptographic libraries
installed @emph{may} be added in the future.
@ -363,7 +363,7 @@ of this package.
If your operating system comes neither with LibreSSL or OpenSSL, you have to
install one manually. It is recommended that you get the latest version of
LibreSSL from @url{http://www.libressl.org/}. Instructions on how to
LibreSSL from @url{https://www.libressl.org/}. Instructions on how to
configure, build and install this package are included within the package.
Please make sure you build development and runtime libraries (which is the
default).
@ -419,7 +419,7 @@ Markus F.X.J. Oberhumer
For the optional compression of UDP packets, tinc uses the functions provided
by the zlib library.
If this library is not installed, you wil get an error when running the
If this library is not installed, you will get an error when running the
configure script. You can either install the zlib library, or disable support
for zlib compression by using the "--disable-zlib" option when running the
configure script. Note that if you disable support for zlib, the resulting
@ -430,20 +430,20 @@ available. Make sure you install the development AND runtime versions
of this package.
If you have to install zlib manually, you can get the source code
from @url{http://www.zlib.net/}. Instructions on how to configure,
from @url{https://zlib.net/}. Instructions on how to configure,
build and install this package are included within the package. Please
make sure you build development and runtime libraries (which is the
default).
@c ==================================================================
@node lzo
@subsection lzo
@node LZO
@subsection LZO
@cindex lzo
@cindex LZO
Another form of compression is offered using the LZO library.
If this library is not installed, you wil get an error when running the
If this library is not installed, you will get an error when running the
configure script. You can either install the LZO library, or disable support
for LZO compression by using the "--disable-lzo" option when running the
configure script. Note that if you disable support for LZO, the resulting
@ -453,7 +453,7 @@ You can use your operating system's package manager to install this if
available. Make sure you install the development AND runtime versions
of this package.
If you have to install lzo manually, you can get the source code
If you have to install LZO manually, you can get the source code
from @url{https://www.oberhumer.com/opensource/lzo/}. Instructions on how to configure,
build and install this package are included within the package. Please
make sure you build development and runtime libraries (which is the
@ -467,15 +467,15 @@ default).
@cindex libcurses
For the "tinc top" command, tinc requires a curses library.
If this library is not installed, you wil get an error when running the
If this library is not installed, you will get an error when running the
configure script. You can either install a suitable curses library, or disable
all functionality that depends on a curses library by using the
"--disable-curses" option when running the configure script.
There are several curses libraries. It is recommended that you install
"ncurses" (@url{http://invisible-island.net/ncurses/}),
"ncurses" (@url{https://invisible-island.net/ncurses/}),
however other curses libraries should also work.
In particular, "PDCurses" (@url{http://pdcurses.sourceforge.net/})
In particular, "PDCurses" (@url{https://pdcurses.sourceforge.io/})
is recommended if you want to compile tinc for Windows.
You can use your operating system's package manager to install this if
@ -490,7 +490,7 @@ of this package.
@cindex libreadline
For the "tinc" command's shell functionality, tinc uses the readline library.
If this library is not installed, you wil get an error when running the
If this library is not installed, you will get an error when running the
configure script. You can either install a suitable readline library, or
disable all functionality that depends on a readline library by using the
"--disable-readline" option when running the configure script.
@ -500,7 +500,7 @@ available. Make sure you install the development AND runtime versions
of this package.
If you have to install libreadline manually, you can get the source code from
@url{http://www.gnu.org/software/readline/}. Instructions on how to configure,
@url{https://www.gnu.org/software/readline/}. Instructions on how to configure,
build and install this package are included within the package. Please make
sure you build development and runtime libraries (which is the default).
@ -691,7 +691,7 @@ you will not find the answers in this documentation.
Make sure you have an adequate understanding of networks in general.
@cindex Network Administrators Guide
A good resource on networking is the
@uref{http://www.tldp.org/LDP/nag2/, Linux Network Administrators Guide}.
@uref{https://www.tldp.org/LDP/nag2/, Linux Network Administrators Guide}.
If you have everything clearly pictured in your mind,
proceed in the following order:
@ -721,7 +721,7 @@ It is not required if you only run one tinc daemon,
it doesn't even have to be the same on all the nodes of your VPN,
but it is recommended that you choose one anyway.
We will asume you use a netname throughout this document.
We will assume you use a netname throughout this document.
This means that you call tinc with the -n argument,
which will specify the netname.
@ -744,22 +744,15 @@ and the host configuration files are expected to be in @file{@value{sysconfdir}/
When tinc starts up, it parses the command-line options and then
reads in the configuration file tinc.conf.
If it sees one or more `ConnectTo' values pointing to other tinc daemons in that file,
it will try to connect to those other daemons.
Whether this succeeds or not and whether `ConnectTo' is specified or not,
tinc will listen for incoming connection from other deamons.
If you did specify a `ConnectTo' value and the other side is not responding,
tinc will keep retrying.
This means that once started, tinc will stay running until you tell it to stop,
and failures to connect to other tinc daemons will not stop your tinc daemon
for trying again later.
This means you don't have to intervene if there are temporary network problems.
It will then start listening for incoming connection from other daemons,
and will by default also automatically try to connect to known peers.
By default, tinc will try to keep at least 3 working meta-connections alive at all times.
@cindex client
@cindex server
There is no real distinction between a server and a client in tinc.
If you wish, you can view a tinc daemon without a `ConnectTo' value as a server,
and one which does specify such a value as a client.
If you wish, you can view a tinc daemon without a `ConnectTo' statement in tinc.conf and `AutoConnect = no' as a server,
and one which does have one or more `ConnectTo' statements or `Autoconnect = yes' (which is the default) as a client.
It does not matter if two tinc daemons have a `ConnectTo' value pointing to each other however.
Connections specified using `ConnectTo' are so-called meta-connections.
@ -778,7 +771,7 @@ It is not always possible to do this however, and firewalls might also prevent d
In that case, VPN packets between A and C will be forwarded by B.
In effect, all nodes in the VPN will be able to talk to each other, as long as
their is a path of meta-connections between them, and whenever possible, two
there is a path of meta-connections between them, and whenever possible, two
nodes will communicate with each other directly.
@ -790,7 +783,7 @@ The actual configuration of the daemon is done in the file
@file{@value{sysconfdir}/tinc/@var{netname}/tinc.conf} and at least one other file in the directory
@file{@value{sysconfdir}/tinc/@var{netname}/hosts/}.
An optionnal directory @file{@value{sysconfdir}/tinc/@var{netname}/conf.d} can be added from which
An optional directory @file{@value{sysconfdir}/tinc/@var{netname}/conf.d} can be added from which
any .conf file will be read.
These file consists of comments (lines started with a #) or assignments
@ -839,7 +832,7 @@ If any is selected, then depending on the operating system
both IPv4 and IPv6 or just IPv6 listening sockets will be created.
@cindex AutoConnect
@item AutoConnect = <yes|no> (no) [experimental]
@item AutoConnect = <yes|no> (yes)
If set to yes, tinc will automatically set up meta connections to other nodes,
without requiring @var{ConnectTo} variables.
@ -900,7 +893,7 @@ in which case outgoing connections to each specified tinc daemon are made.
The names should be known to this tinc daemon
(i.e., there should be a host configuration file for the name on the ConnectTo line).
If you don't specify a host with ConnectTo and don't enable AutoConnect,
If you don't specify a host with ConnectTo and have disabled AutoConnect,
tinc won't try to connect to other daemons at all,
and will instead just listen for incoming connections.
@ -967,7 +960,7 @@ 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
@var{Device}, or @file{@value{localstatedir}/run/@var{netname}.umlsocket}
@var{Device}, or @file{@value{runstatedir}/@var{netname}.umlsocket}
if not specified.
Tinc will wait for a User Mode Linux instance to connect to this socket.
@ -975,7 +968,7 @@ Tinc will wait for a User Mode Linux instance to connect to this socket.
@item vde (not compiled in by default)
Uses the libvdeplug library to connect to a Virtual Distributed Ethernet switch,
using the UNIX socket specified by
@var{Device}, or @file{@value{localstatedir}/run/vde.ctl}
@var{Device}, or @file{@value{runstatedir}/vde.ctl}
if not specified.
@end table
@ -1048,11 +1041,19 @@ Incoming packets that are meant for another node are forwarded by tinc internall
This is the default mode, and unless you really know you need another forwarding mode, don't change it.
@item kernel
Incoming packets are always sent to the TUN/TAP device, even if the packets are not for the local node.
Incoming packets using the legacy protocol are always sent to the TUN/TAP device,
even if the packets are not for the local node.
This is less efficient, but allows the kernel to apply its routing and firewall rules on them,
and can also help debugging.
Incoming packets using the SPTPS protocol are dropped, since they are end-to-end encrypted.
@end table
@cindex FWMark
@item FWMark = <@var{value}> (0) [experimental]
When set to a non-zero value, all TCP and UDP sockets created by tinc will use the given value as the firewall mark.
This can be used for mark-based routing or for packet filtering.
This option is currently only supported on Linux.
@cindex Hostnames
@item Hostnames = <yes|no> (no)
This option selects whether IP addresses (both real and on the VPN)
@ -1179,7 +1180,7 @@ will be inherited by the UDP packets that are sent out.
@item PrivateKey = <@var{key}> [obsolete]
This is the RSA private key for tinc. However, for safety reasons it is
advised to store private keys of any kind in separate files. This prevents
accidental eavesdropping if you are editting the configuration file.
accidental eavesdropping if you are editing the configuration file.
@cindex PrivateKeyFile
@item PrivateKeyFile = <@var{path}> (@file{@value{sysconfdir}/tinc/@var{netname}/rsa_key.priv})
@ -1335,7 +1336,7 @@ Fragmentation Needed or Packet too Big messages are dropped by firewalls.
@item Compression = <@var{level}> (0)
This option sets the level of compression used for UDP packets.
Possible values are 0 (off), 1 (fast zlib) and any integer up to 9 (best zlib),
10 (fast lzo) and 11 (best lzo).
10 (fast LZO) and 11 (best LZO).
@cindex Digest
@item Digest = <@var{digest}> (sha1)
@ -1396,7 +1397,7 @@ connection with that host.
@cindex Subnet
@item Subnet = <@var{address}[/@var{prefixlength}[#@var{weight}]]>
The subnet which this tinc daemon will serve.
Tinc tries to look up which other daemon it should send a packet to by searching the appropiate subnet.
Tinc tries to look up which other daemon it should send a packet to by searching the appropriate subnet.
If the packet matches a subnet,
it will be sent to the daemon who has this subnet in his host configuration file.
Multiple subnet lines can be specified for each daemon.
@ -1626,23 +1627,11 @@ For example, if your hostname is foo.example.org, run:
tinc -n @var{netname} add address foo.example.org
@end example
If you already know to which daemons your daemon should make meta-connections,
you should configure that now as well.
Suppose you want to connect to a daemon named "bar", run:
@example
tinc -n @var{netname} add connectto bar
@end example
Note that you specify the Name of the other daemon here, not an IP address or hostname!
When you start tinc, and it tries to make a connection to "bar",
it will look for a host configuration file named @file{hosts/bar},
and will read Address statements and public keys from that file.
@subsubheading Step 2. Exchanging configuration files.
If your daemon has a ConnectTo = bar statement in its @file{tinc.conf} file,
or if bar has a ConnectTo your daemon, then you both need each other's host configuration files.
In order for two tinc daemons to be able to connect to each other,
they each need the other's host configuration files.
So if you want foo to be able to connect with bar,
You should send @file{hosts/@var{name}} to bar, and bar should send you his file which you should move to @file{hosts/bar}.
If you are on a UNIX platform, you can easily send an email containing the necessary information using the following command
(assuming the owner of bar has the email address bar@@example.org):
@ -1668,10 +1657,9 @@ tinc -n @var{netname} export \
| tinc -n @var{netname} import
@end example
You should repeat this for all nodes you ConnectTo, or which ConnectTo you.
However, remember that you do not need to ConnectTo all nodes in the VPN;
it is only necessary to create one or a few meta-connections,
after the connections are made tinc will learn about all the other nodes in the VPN,
You can repeat this for a few other nodes as well.
It is not necessary to manually exchange host config files between all nodes;
after the initial connections are made tinc will learn about all the other nodes in the VPN,
and will automatically make other connections as necessary.
@ -1817,12 +1805,10 @@ and in @file{@value{sysconfdir}/tinc/company/tinc.conf}:
@example
Name = BranchB
ConnectTo = BranchA
@end example
Note here that the internal address (on eth0) doesn't have to be the
same as on the VPN interface. Also, ConnectTo is given so that this node will
always try to connect to BranchA.
same as on the VPN interface.
On all hosts, in @file{@value{sysconfdir}/tinc/company/hosts/BranchB}:
@ -1853,7 +1839,6 @@ and in @file{@value{sysconfdir}/tinc/company/tinc.conf}:
@example
Name = BranchC
ConnectTo = BranchA
@end example
C already has another daemon that runs on port 655, so they have to
@ -1890,7 +1875,6 @@ and in @file{@value{sysconfdir}/tinc/company/tinc.conf}:
@example
Name = BranchD
ConnectTo = BranchC
@end example
D will be connecting to C, which has a tincd running for this network on
@ -1983,7 +1967,7 @@ Specifying . for @var{netname} is the same as not specifying any @var{netname}.
@item --pidfile=@var{filename}
Store a cookie in @var{filename} which allows tinc to authenticate.
If unspecified, the default is
@file{@value{localstatedir}/run/tinc.@var{netname}.pid}.
@file{@value{runstatedir}/tinc.@var{netname}.pid}.
@item -o, --option=[@var{HOST}.]@var{KEY}=@var{VALUE}
Without specifying a @var{HOST}, this will set server configuration variable @var{KEY} to @var{VALUE}.
@ -2001,6 +1985,9 @@ This option is not supported on all platforms.
Write log entries to a file instead of to the system logging facility.
If @var{file} is omitted, the default is @file{@value{localstatedir}/log/tinc.@var{netname}.log}.
@item --pidfile=@var{file}
Write PID to @var{file} instead of @file{@value{runstatedir}/tinc.@var{netname}.pid}.
@item --bypass-security
Disables encryption and authentication.
Only useful for debugging.
@ -2012,10 +1999,14 @@ located (@file{@value{sysconfdir}/tinc/@var{netname}/} as determined by
The chroot is performed after all the initialization is done, after
writing pid files and opening network sockets.
Note that this option alone does not do any good without -U/--user, below.
This option is best used in combination with the -U/--user option described below.
Note also that tinc can't run scripts anymore (such as tinc-down or host-up),
unless it's setup to be runnable inside chroot environment.
You will need to ensure the chroot environment contains all the files necessary
for tinc to run correctly.
Most importantly, for tinc to be able to resolve hostnames inside the chroot environment,
you must copy @file{/etc/resolv.conf} into the chroot directory.
If you want to be able to run scripts other than @file{tinc-up} in the chroot,
you must ensure the appropriate shell is also installed in the chroot, along with all its dependencies.
This option is not supported on all platforms.
@item -U, --user=@var{user}
@ -2295,7 +2286,11 @@ Use configuration for net @var{netname}. @xref{Multiple networks}.
@item --pidfile=@var{filename}
Use the cookie from @var{filename} to authenticate with a running tinc daemon.
If unspecified, the default is
@file{@value{localstatedir}/run/tinc.@var{netname}.pid}.
@file{@value{runstatedir}/tinc.@var{netname}.pid}.
@cindex batch
@item -b, --batch
Don't ask for anything (non-interactive mode).
@item --force
Force some commands to work despite warnings.
@ -2523,7 +2518,7 @@ The @var{name} of the node must be given,
or can be "." to check against the local node's public key,
or "*" to allow a signature from any node whose public key is known.
If no @var{filename} is given, the file is read from standard input.
If the verification is succesful, a copy of the input with the signature removed is written to standard output, and the exit code will be zero.
If the verification is successful, a copy of the input with the signature removed is written to standard output, and the exit code will be zero.
If the verification failed, nothing will be written to standard output, and the exit code will be non-zero.
@end table
@ -2546,7 +2541,7 @@ Examples of changing the configuration using tinc:
tinc -n vpn init foo
tinc -n vpn add Subnet 192.168.1.0/24
tinc -n vpn add bar.Address bar.example.com
tinc -n vpn add ConnectTo bar
tinc -n vpn set Mode switch
tinc -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@@example.com
@end example
@ -2571,7 +2566,7 @@ Intervals lower than 0.1 seconds are not allowed.
@item c
Toggle between displaying current traffic rates (in packets and bytes per second)
and cummulative traffic (total packets and bytes since the tinc daemon started).
and cumulative traffic (total packets and bytes since the tinc daemon started).
@item n
Sort the list of nodes by name.
@ -2696,6 +2691,8 @@ Address = server.example.com
The file is basically a concatenation of several host config blocks. Each host
config block starts with @code{Name = ...}. Lines that look like @code{#---#}
are not important, it just makes it easier for humans to read the file.
However, the first line of an invitation file @emph{must} always start with
@code{Name = ...}.
The first host config block is always the one representing the invitee. So the
first Name statement determines the name that the invitee will get. From the
@ -2744,7 +2741,7 @@ When an invitation is generated, the "invitation-created" script is called (if
it exists) right after the invitation file is written, but before the URL has
been written to stdout. This allows one to change the invitation file
automatically before the invitation URL is passed to the invitee. Here is an
example shell script that aproximately recreates the default invitation file:
example shell script that approximately recreates the default invitation file:
@example
#!/bin/sh
@ -2846,7 +2843,7 @@ In switch or hub modes ARP does work so the sender already knows the correct des
In those modes every interface should have a unique MAC address, so make sure they are not the same.
Because switch and hub modes rely on MAC addresses to function correctly,
these modes cannot be used on the following operating systems which don't have a `tap' style virtual network device:
OpenBSD, NetBSD, Darwin and Solaris.
NetBSD, Darwin and Solaris.
@c ==================================================================
@ -3378,13 +3375,27 @@ that tinc's default length of 4 bytes for the MAC is too short, and he doesn't
like tinc's use of RSA during authentication. We do not know of a security hole
in the legacy protocol of tinc, but it is not as strong as TLS or IPsec.
This version of tinc comes with an improved protocol, called Simple Peer-to-Peer Security,
which aims to be as strong as TLS with one of the strongest cipher suites.
The Sweet32 attack affects versions of tinc prior to 1.0.30.
On September 6th, 2018, Michael Yonly contacted us and provided
proof-of-concept code that allowed a remote attacker to create an
authenticated, one-way connection with a node, and also that there was a
possibility for a man-in-the-middle to force UDP packets from a node to be sent
in plaintext. The first issue was trivial to exploit on tinc versions prior to
1.0.30, but the changes in 1.0.30 to mitigate the Sweet32 attack made this
weakness much harder to exploit. These issues have been fixed in tinc 1.0.35.
This version of tinc comes with an improved protocol, called Simple
Peer-to-Peer Security (SPTPS), which aims to be as strong as TLS with one of
the strongest cipher suites. None of the above security issues affected SPTPS.
However, be aware that SPTPS is only used between nodes running tinc 1.1pre* or
later, and in a VPN with nodes running different versions, the security might
only be as good as that of the oldest version.
Cryptography is a hard thing to get right. We cannot make any
guarantees. Time, review and feedback are the only things that can
prove the security of any cryptographic product. If you wish to review
tinc or give us feedback, you are stronly encouraged to do so.
tinc or give us feedback, you are strongly encouraged to do so.
@c ==================================================================
@ -3394,6 +3405,7 @@ tinc or give us feedback, you are stronly encouraged to do so.
@menu
* Interface configuration::
* Routes::
* Automatically starting tinc::
@end menu
@c ==================================================================
@ -3450,13 +3462,6 @@ For IPv6 addresses:
@tab @code{netsh interface ipv6 add address} @var{interface} @code{static} @var{address}/@var{prefixlength}
@end multitable
On some platforms, when running tinc in switch mode, the VPN interface must be set to tap mode with an ifconfig command:
@multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface}
@item OpenBSD
@tab @code{ifconfig} @var{interface} @code{link0}
@end multitable
On Linux, it is possible to create a persistent tun/tap interface which will
continue to exist even if tinc quit, although this is normally not required.
It can be useful to set up a tun/tap interface owned by a non-root user, so
@ -3520,6 +3525,67 @@ Adding routes to IPv6 subnets:
@tab @code{netsh interface ipv6 add route} @var{network address}/@var{prefixlength} @var{interface}
@end multitable
@c ==================================================================
@node Automatically starting tinc
@section Automatically starting tinc
@menu
* Linux::
* Windows::
* Other platforms::
@end menu
@c ==================================================================
@node Linux
@subsection Linux
@cindex systemd
There are many Linux distributions, and historically, many of them had their
own way of starting programs at boot time. Today, a number of major Linux
distributions have chosen to use systemd as their init system. Tinc ships with
systemd service files that allow you to start and stop tinc using systemd.
There are two service files: @code{tinc.service} is used to globally enable or
disable all tinc daemons managed by systemd, and
@code{tinc@@@var{netname}.service} is used to enable or disable specific tinc
daemons. So if one has created a tinc network with netname @code{foo}, then
you have to run the following two commands to ensure it is started at boot
time:
@example
systemctl enable tinc
systemctl enable tinc@@foo
@end example
To start the tinc daemon immediately if it wasn't already running, use the
following command:
@example
systemctl start tinc@@foo
@end example
You can also use @samp{systemctl start tinc}, this will start all tinc daemons
that are enabled. You can stop and disable tinc networks in the same way.
If your system is not using systemd, then you have to look up your
distribution's way of starting tinc at boot time.
@c ==================================================================
@node Windows
@subsection Windows
On Windows, if tinc is started with the @code{tinc start} command without using
the @code{-D} or @code{--no-detach} option, it will automatically register
itself as a service that is started at boot time. When tinc is stopped using
the @code{tinc stop} command, it will also automatically unregister itself.
Once tinc is registered as a service, it is also possible to stop and start
tinc using the Windows Services Manager.
@c ==================================================================
@node Other platforms
@subsection Other platforms
On platforms other than the ones mentioned in the earlier sections, you have to
look up your platform's way of starting programs at boot time.
@c ==================================================================
@node About us

View file

@ -100,7 +100,7 @@ to authenticate.
If
.Ar FILE
is omitted, the default is
.Pa @localstatedir@/run/tinc. Ns Ar NETNAME Ns Pa .pid.
.Pa @runstatedir@/tinc. Ns Ar NETNAME Ns Pa .pid.
.It Fl -bypass-security
Disables encryption and authentication of the meta protocol.
Only useful for debugging.
@ -173,7 +173,7 @@ This will log all network traffic over the virtual private network.
Directory containing the configuration files tinc uses.
For more information, see
.Xr tinc.conf 5 .
.It Pa @localstatedir@/run/tinc. Ns Ar NETNAME Ns Pa .pid
.It Pa @runstatedir@/tinc. Ns Ar NETNAME Ns Pa .pid
The PID of the currently running
.Nm
is stored in this file.

5
doc/tincinclude.texi Normal file
View file

@ -0,0 +1,5 @@
@set VERSION 1.1pre17
@set PACKAGE tinc
@set sysconfdir /etc
@set localstatedir /var
@set runstatedir /var/run

View file

@ -2,3 +2,4 @@
@set PACKAGE @PACKAGE@
@set sysconfdir @sysconfdir@
@set localstatedir @localstatedir@
@set runstatedir @runstatedir@

View file

@ -1,3 +0,0 @@
dist_bin_SCRIPTS = tinc-gui
extra_DIST = README.gui

View file

@ -1,507 +0,0 @@
# Makefile.in generated by automake 1.15.1 from Makefile.am.
# @configure_input@
# 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,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = gui
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
$(top_srcdir)/m4/ax_append_flag.m4 \
$(top_srcdir)/m4/ax_cflags_warn_all.m4 \
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
$(top_srcdir)/m4/ax_check_link_flag.m4 \
$(top_srcdir)/m4/ax_require_defined.m4 \
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \
$(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \
$(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \
$(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(dist_bin_SCRIPTS) \
$(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(bindir)"
SCRIPTS = $(dist_bin_SCRIPTS)
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CURSES_LIBS = @CURSES_LIBS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MINIUPNPC_LIBS = @MINIUPNPC_LIBS@
MKDIR_P = @MKDIR_P@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
READLINE_LIBS = @READLINE_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
systemd_path = @systemd_path@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
dist_bin_SCRIPTS = tinc-gui
extra_DIST = README.gui
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu gui/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu gui/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-dist_binSCRIPTS: $(dist_bin_SCRIPTS)
@$(NORMAL_INSTALL)
@list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
$(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
done | \
sed -e 'p;s,.*/,,;n' \
-e 'h;s|.*|.|' \
-e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
{ d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
if ($$2 == $$4) { files[d] = files[d] " " $$1; \
if (++n[d] == $(am__install_max)) { \
print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
else { print "f", d "/" $$4, $$1 } } \
END { for (d in files) print "f", d, files[d] }' | \
while read type dir files; do \
if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
test -z "$$files" || { \
echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \
$(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
} \
; done
uninstall-dist_binSCRIPTS:
@$(NORMAL_UNINSTALL)
@list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \
files=`for p in $$list; do echo "$$p"; done | \
sed -e 's,.*/,,;$(transform)'`; \
dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir)
installcheck-dist_binSCRIPTS: $(dist_bin_SCRIPTS)
bad=0; pid=$$$$; list="$(dist_bin_SCRIPTS)"; for p in $$list; do \
case ' $(AM_INSTALLCHECK_STD_OPTIONS_EXEMPT) ' in \
*" $$p "* | *" $(srcdir)/$$p "*) continue;; \
esac; \
f=`echo "$$p" | sed 's,^.*/,,;$(transform)'`; \
for opt in --help --version; do \
if "$(DESTDIR)$(bindir)/$$f" $$opt >c$${pid}_.out \
2>c$${pid}_.err </dev/null \
&& test -n "`cat c$${pid}_.out`" \
&& test -z "`cat c$${pid}_.err`"; then :; \
else echo "$$f does not support $$opt" 1>&2; bad=1; fi; \
done; \
done; rm -f c$${pid}_.???; exit $$bad
tags TAGS:
ctags CTAGS:
cscope cscopelist:
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(SCRIPTS)
installdirs:
for dir in "$(DESTDIR)$(bindir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-dist_binSCRIPTS
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am: installcheck-dist_binSCRIPTS
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-dist_binSCRIPTS
.MAKE: install-am install-strip
.PHONY: all all-am check check-am clean clean-generic cscopelist-am \
ctags-am distclean distclean-generic distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dist_binSCRIPTS 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-strip installcheck installcheck-am \
installcheck-dist_binSCRIPTS installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
pdf-am ps ps-am tags-am uninstall uninstall-am \
uninstall-dist_binSCRIPTS
.PRECIOUS: Makefile
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View file

@ -1,634 +0,0 @@
#!/usr/bin/env python2
# tinc-gui -- GUI for controlling a running tincd
# Copyright (C) 2009-2014 Guus Sliepen <guus@tinc-vpn.org>
# 2014 Dennis Joachimsthaler <dennis@efjot.de>
#
# 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.
import string
import socket
import os
import platform
import time
from argparse import ArgumentParser
import wx
from wx.lib.mixins.listctrl import ColumnSorterMixin
from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin
if platform.system() == 'Windows':
import _winreg
# Classes to interface with a running tinc daemon
REQ_STOP = 0
REQ_RELOAD = 1
REQ_RESTART = 2
REQ_DUMP_NODES = 3
REQ_DUMP_EDGES = 4
REQ_DUMP_SUBNETS = 5
REQ_DUMP_CONNECTIONS = 6
REQ_DUMP_GRAPH = 7
REQ_PURGE = 8
REQ_SET_DEBUG = 9
REQ_RETRY = 10
REQ_CONNECT = 11
REQ_DISCONNECT = 12
ID = 0
ACK = 4
CONTROL = 18
class Node(object):
def __init__(self, args):
self.name = args[0]
self.id = args[1]
self.address = args[2]
self.port = args[4]
self.cipher = int(args[5])
self.digest = int(args[6])
self.maclength = int(args[7])
self.compression = int(args[8])
self.options = int(args[9], 0x10)
self.status = int(args[10], 0x10)
self.nexthop = args[11]
self.via = args[12]
self.distance = int(args[13])
self.pmtu = int(args[14])
self.minmtu = int(args[15])
self.maxmtu = int(args[16])
self.last_state_change = float(args[17])
self.subnets = {}
class Edge(object):
def __init__(self, args):
self.source = args[0]
self.sink = args[1]
self.address = args[2]
self.port = args[4]
self.options = int(args[-2], 16)
self.weight = int(args[-1])
class Subnet(object):
def __init__(self, args):
if args[0].find('#') >= 0:
address, self.weight = args[0].split('#', 1)
else:
self.weight = 10
address = args[0]
if address.find('/') >= 0:
self.address, self.prefixlen = address.split('/', 1)
else:
self.address = address
self.prefixlen = '48'
self.owner = args[1]
class Connection(object):
def __init__(self, args):
self.name = args[0]
self.address = args[1]
self.port = args[3]
self.options = int(args[4], 0x10)
self.socket = int(args[5])
self.status = int(args[6], 0x10)
self.weight = 'n/a'
class VPN(object):
def __init__(self, netname=None, pidfile=None, confdir='/etc/tinc', piddir='/run'):
if platform.system() == 'Windows':
sam = _winreg.KEY_READ
if platform.machine().endswith('64'):
sam = sam | _winreg.KEY_WOW64_64KEY
try:
reg = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE)
try:
key = _winreg.OpenKey(reg, "SOFTWARE\\tinc", 0, sam)
except WindowsError:
key = _winreg.OpenKey(reg, "SOFTWARE\\Wow6432Node\\tinc", 0, sam)
confdir = _winreg.QueryValue(key, None)
except WindowsError:
pass
if netname:
self.netname = netname
self.confbase = os.path.join(confdir, netname)
else:
self.confbase = confdir
self.tincconf = os.path.join(self.confbase, 'tinc.conf')
if pidfile is not None:
self.pidfile = pidfile
else:
if platform.system() == 'Windows':
self.pidfile = os.path.join(self.confbase, 'pid')
else:
if netname:
self.pidfile = os.path.join(piddir, 'tinc.' + netname + '.pid')
else:
self.pidfile = os.path.join(piddir, 'tinc.pid')
self.sf = None
self.name = None
self.port = None
self.nodes = {}
self.edges = {}
self.subnets = {}
self.connections = {}
def connect(self):
# read the pidfile
f = open(self.pidfile)
info = string.split(f.readline())
f.close()
# check if there is a UNIX socket as well
if self.pidfile.endswith('.pid'):
unixfile = self.pidfile.replace('.pid', '.socket');
else:
unixfile = self.pidfile + '.socket';
if os.path.exists(unixfile):
# use it if it exists
print(unixfile + " exists!");
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect(unixfile)
else:
# otherwise connect via TCP
print(unixfile + " does not exist.");
if ':' in info[2]:
af = socket.AF_INET6
else:
af = socket.AF_INET
s = socket.socket(af, socket.SOCK_STREAM)
s.connect((info[2], int(info[4])))
self.sf = s.makefile()
s.close()
hello = string.split(self.sf.readline())
self.name = hello[1]
self.sf.write('0 ^' + info[1] + ' 17\r\n')
self.sf.flush()
resp = string.split(self.sf.readline())
self.port = info[4]
self.refresh()
def refresh(self):
for request in (REQ_DUMP_NODES, REQ_DUMP_EDGES, REQ_DUMP_SUBNETS, REQ_DUMP_CONNECTIONS):
self.sf.write('{} {}\r\n'.format(CONTROL, request))
self.sf.flush()
for node in self.nodes.values():
node.visited = False
for edge in self.edges.values():
edge.visited = False
for subnet in self.subnets.values():
subnet.visited = False
for connections in self.connections.values():
connections.visited = False
while True:
resp = string.split(self.sf.readline())
if len(resp) < 2:
break
if resp[0] != '18':
break
if resp[1] == '3':
if len(resp) < 19:
continue
node = self.nodes.get(resp[2]) or Node(resp[2:])
node.visited = True
self.nodes[resp[2]] = node
elif resp[1] == '4':
if len(resp) < 9:
continue
edge = self.nodes.get((resp[2], resp[3])) or Edge(resp[2:])
edge.visited = True
self.edges[(resp[2], resp[3])] = edge
elif resp[1] == '5':
if len(resp) < 4:
continue
subnet = self.subnets.get((resp[2], resp[3])) or Subnet(resp[2:])
subnet.visited = True
self.subnets[(resp[2], resp[3])] = subnet
if subnet.owner == "(broadcast)":
continue
self.nodes[subnet.owner].subnets[resp[2]] = subnet
elif resp[1] == '6':
if len(resp) < 9:
break
connection = self.connections.get((resp[2], resp[3], resp[5])) or Connection(resp[2:])
connection.visited = True
self.connections[(resp[2], resp[3], resp[5])] = connection
else:
break
for key, subnet in self.subnets.items():
if not subnet.visited:
del self.subnets[key]
for key, edge in self.edges.items():
if not edge.visited:
del self.edges[key]
for key, node in self.nodes.items():
if not node.visited:
del self.nodes[key]
else:
for key, subnet in node.subnets.items():
if not subnet.visited:
del node.subnets[key]
for key, connection in self.connections.items():
if not connection.visited:
del self.connections[key]
def close(self):
self.sf.close()
def disconnect(self, name):
self.sf.write('18 12 ' + name + '\r\n')
self.sf.flush()
resp = string.split(self.sf.readline())
def debug(self, level=-1):
self.sf.write('18 9 ' + str(level) + '\r\n')
self.sf.flush()
resp = string.split(self.sf.readline())
return int(resp[2])
class SuperListCtrl(wx.ListCtrl, ColumnSorterMixin, ListCtrlAutoWidthMixin):
def __init__(self, parent, style):
wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT | wx.LC_HRULES | wx.LC_VRULES)
ListCtrlAutoWidthMixin.__init__(self)
ColumnSorterMixin.__init__(self, 16)
def GetListCtrl(self):
return self
class SettingsPage(wx.Panel):
def on_debug_level(self, event):
vpn.debug(self.debug.GetValue())
def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id)
grid = wx.FlexGridSizer(cols=2)
grid.AddGrowableCol(1, 1)
namelabel = wx.StaticText(self, -1, 'Name:')
self.name = wx.TextCtrl(self, -1, vpn.name)
grid.Add(namelabel)
grid.Add(self.name, 1, wx.EXPAND)
portlabel = wx.StaticText(self, -1, 'Port:')
self.port = wx.TextCtrl(self, -1, vpn.port)
grid.Add(portlabel)
grid.Add(self.port)
debuglabel = wx.StaticText(self, -1, 'Debug level:')
self.debug = wx.SpinCtrl(self, min=0, max=5, initial=vpn.debug())
self.debug.Bind(wx.EVT_SPINCTRL, self.on_debug_level)
grid.Add(debuglabel)
grid.Add(self.debug)
modelabel = wx.StaticText(self, -1, 'Mode:')
self.mode = wx.ComboBox(self, -1, style=wx.CB_READONLY, value='Router', choices=['Router', 'Switch', 'Hub'])
grid.Add(modelabel)
grid.Add(self.mode)
self.SetSizer(grid)
class ConnectionsPage(wx.Panel):
def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id)
self.list = SuperListCtrl(self, id)
self.list.InsertColumn(0, 'Name')
self.list.InsertColumn(1, 'Address')
self.list.InsertColumn(2, 'Port')
self.list.InsertColumn(3, 'Options')
self.list.InsertColumn(4, 'Weight')
hbox = wx.BoxSizer(wx.HORIZONTAL)
hbox.Add(self.list, 1, wx.EXPAND)
self.SetSizer(hbox)
self.refresh()
class ContextMenu(wx.Menu):
def __init__(self, item):
wx.Menu.__init__(self)
self.item = item
disconnect = wx.MenuItem(self, -1, 'Disconnect')
self.AppendItem(disconnect)
self.Bind(wx.EVT_MENU, self.on_disconnect, id=disconnect.GetId())
def on_disconnect(self, event):
vpn.disconnect(self.item[0])
def on_context(self, event):
idx = event.GetIndex()
self.PopupMenu(self.ContextMenu(self.list.itemDataMap[event.GetIndex()]), event.GetPosition())
def refresh(self):
sortstate = self.list.GetSortState()
self.list.itemDataMap = {}
i = 0
for key, connection in vpn.connections.items():
if self.list.GetItemCount() <= i:
self.list.InsertStringItem(i, connection.name)
else:
self.list.SetStringItem(i, 0, connection.name)
self.list.SetStringItem(i, 1, connection.address)
self.list.SetStringItem(i, 2, connection.port)
self.list.SetStringItem(i, 3, str(connection.options))
self.list.SetStringItem(i, 4, str(connection.weight))
self.list.itemDataMap[i] = (connection.name, connection.address, connection.port, connection.options,
connection.weight)
self.list.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.on_context)
self.list.SetItemData(i, i)
i += 1
while self.list.GetItemCount() > i:
self.list.DeleteItem(self.list.GetItemCount() - 1)
self.list.SortListItems(sortstate[0], sortstate[1])
class NodesPage(wx.Panel):
def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id)
self.list = SuperListCtrl(self, id)
self.list.InsertColumn(0, 'Name')
self.list.InsertColumn(1, 'Address')
self.list.InsertColumn(2, 'Port')
self.list.InsertColumn(3, 'Cipher')
self.list.InsertColumn(4, 'Digest')
self.list.InsertColumn(5, 'MACLength')
self.list.InsertColumn(6, 'Compression')
self.list.InsertColumn(7, 'Options')
self.list.InsertColumn(8, 'Status')
self.list.InsertColumn(9, 'Nexthop')
self.list.InsertColumn(10, 'Via')
self.list.InsertColumn(11, 'Distance')
self.list.InsertColumn(12, 'PMTU')
self.list.InsertColumn(13, 'Min MTU')
self.list.InsertColumn(14, 'Max MTU')
self.list.InsertColumn(15, 'Since')
hbox = wx.BoxSizer(wx.HORIZONTAL)
hbox.Add(self.list, 1, wx.EXPAND)
self.SetSizer(hbox)
self.refresh()
def refresh(self):
sortstate = self.list.GetSortState()
self.list.itemDataMap = {}
i = 0
for key, node in vpn.nodes.items():
if self.list.GetItemCount() <= i:
self.list.InsertStringItem(i, node.name)
else:
self.list.SetStringItem(i, 0, node.name)
self.list.SetStringItem(i, 1, node.address)
self.list.SetStringItem(i, 2, node.port)
self.list.SetStringItem(i, 3, str(node.cipher))
self.list.SetStringItem(i, 4, str(node.digest))
self.list.SetStringItem(i, 5, str(node.maclength))
self.list.SetStringItem(i, 6, str(node.compression))
self.list.SetStringItem(i, 7, format(node.options, "x"))
self.list.SetStringItem(i, 8, format(node.status, "04x"))
self.list.SetStringItem(i, 9, node.nexthop)
self.list.SetStringItem(i, 10, node.via)
self.list.SetStringItem(i, 11, str(node.distance))
self.list.SetStringItem(i, 12, str(node.pmtu))
self.list.SetStringItem(i, 13, str(node.minmtu))
self.list.SetStringItem(i, 14, str(node.maxmtu))
if node.last_state_change:
since = time.strftime("%Y-%m-%d %H:%M", time.localtime(node.last_state_change))
else:
since = "never"
self.list.SetStringItem(i, 15, since)
self.list.itemDataMap[i] = (node.name, node.address, node.port, node.cipher, node.digest, node.maclength,
node.compression, node.options, node.status, node.nexthop, node.via,
node.distance, node.pmtu, node.minmtu, node.maxmtu, since)
self.list.SetItemData(i, i)
i += 1
while self.list.GetItemCount() > i:
self.list.DeleteItem(self.list.GetItemCount() - 1)
self.list.SortListItems(sortstate[0], sortstate[1])
class EdgesPage(wx.Panel):
def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id)
self.list = SuperListCtrl(self, id)
self.list.InsertColumn(0, 'From')
self.list.InsertColumn(1, 'To')
self.list.InsertColumn(2, 'Address')
self.list.InsertColumn(3, 'Port')
self.list.InsertColumn(4, 'Options')
self.list.InsertColumn(5, 'Weight')
hbox = wx.BoxSizer(wx.HORIZONTAL)
hbox.Add(self.list, 1, wx.EXPAND)
self.SetSizer(hbox)
self.refresh()
def refresh(self):
sortstate = self.list.GetSortState()
self.list.itemDataMap = {}
i = 0
for key, edge in vpn.edges.items():
if self.list.GetItemCount() <= i:
self.list.InsertStringItem(i, edge.source)
else:
self.list.SetStringItem(i, 0, edge.source)
self.list.SetStringItem(i, 1, edge.sink)
self.list.SetStringItem(i, 2, edge.address)
self.list.SetStringItem(i, 3, edge.port)
self.list.SetStringItem(i, 4, format(edge.options, "x"))
self.list.SetStringItem(i, 5, str(edge.weight))
self.list.itemDataMap[i] = (edge.source, edge.sink, edge.address, edge.port, edge.options, edge.weight)
self.list.SetItemData(i, i)
i += 1
while self.list.GetItemCount() > i:
self.list.DeleteItem(self.list.GetItemCount() - 1)
self.list.SortListItems(sortstate[0], sortstate[1])
class SubnetsPage(wx.Panel):
def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id)
self.list = SuperListCtrl(self, id)
self.list.InsertColumn(0, 'Subnet', wx.LIST_FORMAT_RIGHT)
self.list.InsertColumn(1, 'Weight', wx.LIST_FORMAT_RIGHT)
self.list.InsertColumn(2, 'Owner')
hbox = wx.BoxSizer(wx.HORIZONTAL)
hbox.Add(self.list, 1, wx.EXPAND)
self.SetSizer(hbox)
self.refresh()
def refresh(self):
sortstate = self.list.GetSortState()
self.list.itemDataMap = {}
i = 0
for key, subnet in vpn.subnets.items():
if self.list.GetItemCount() <= i:
self.list.InsertStringItem(i, subnet.address + '/' + subnet.prefixlen)
else:
self.list.SetStringItem(i, 0, subnet.address + '/' + subnet.prefixlen)
self.list.SetStringItem(i, 1, str(subnet.weight))
self.list.SetStringItem(i, 2, subnet.owner)
self.list.itemDataMap[i] = (subnet.address + '/' + subnet.prefixlen, subnet.weight, subnet.owner)
self.list.SetItemData(i, i)
i += 1
while self.list.GetItemCount() > i:
self.list.DeleteItem(self.list.GetItemCount() - 1)
self.list.SortListItems(sortstate[0], sortstate[1])
class StatusPage(wx.Panel):
def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id)
class GraphPage(wx.Window):
def __init__(self, parent, id):
wx.Window.__init__(self, parent, id)
class NetPage(wx.Notebook):
def __init__(self, parent, id):
wx.Notebook.__init__(self, parent)
self.settings = SettingsPage(self, id)
self.connections = ConnectionsPage(self, id)
self.nodes = NodesPage(self, id)
self.edges = EdgesPage(self, id)
self.subnets = SubnetsPage(self, id)
self.graph = GraphPage(self, id)
self.status = StatusPage(self, id)
self.AddPage(self.settings, 'Settings')
# self.AddPage(self.status, 'Status')
self.AddPage(self.connections, 'Connections')
self.AddPage(self.nodes, 'Nodes')
self.AddPage(self.edges, 'Edges')
self.AddPage(self.subnets, 'Subnets')
# self.AddPage(self.graph, 'Graph')
class MainWindow(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title)
menubar = wx.MenuBar()
menu = wx.Menu()
menu.Append(1, '&Quit\tCtrl-X', 'Quit tinc GUI')
menubar.Append(menu, '&File')
# nb = wx.Notebook(self, -1)
# nb.SetPadding((0, 0))
self.np = NetPage(self, -1)
# nb.AddPage(np, 'VPN')
self.timer = wx.Timer(self, -1)
self.Bind(wx.EVT_TIMER, self.on_timer, self.timer)
self.timer.Start(1000)
self.Bind(wx.EVT_MENU, self.on_quit, id=1)
self.SetMenuBar(menubar)
self.Show()
def on_quit(self, event):
app.ExitMainLoop()
def on_timer(self, event):
vpn.refresh()
self.np.nodes.refresh()
self.np.subnets.refresh()
self.np.edges.refresh()
self.np.connections.refresh()
def main(netname, pidfile):
global vpn, app
if netname is None:
netname = os.getenv('NETNAME')
vpn = VPN(netname, pidfile)
vpn.connect()
app = wx.App()
mw = MainWindow(None, -1, 'Tinc GUI')
"""
def OnTaskBarIcon(event):
mw.Raise()
"""
"""
icon = wx.Icon("tincgui.ico", wx.BITMAP_TYPE_PNG)
taskbaricon = wx.TaskBarIcon()
taskbaricon.SetIcon(icon, 'Tinc GUI')
wx.EVT_TASKBAR_RIGHT_UP(taskbaricon, OnTaskBarIcon)
"""
app.MainLoop()
vpn.close()
if __name__ == '__main__':
argparser = ArgumentParser(epilog='Report bugs to tinc@tinc-vpn.org.')
argparser.add_argument('-n', '--net', metavar='NETNAME', dest='netname', help='Connect to net NETNAME')
argparser.add_argument('-p', '--pidfile', help='Path to the pid file (containing the controlcookie)')
options = argparser.parse_args()
main(options.netname, options.pidfile)

View file

@ -1,7 +1,7 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2014-09-12.12; # UTC
scriptversion=2018-03-11.20; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
@ -271,15 +271,18 @@ do
fi
dst=$dst_arg
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
# If destination is a directory, append the input filename.
if test -d "$dst"; then
if test "$is_target_a_directory" = never; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstbase=`basename "$src"`
case $dst in
*/) dst=$dst$dstbase;;
*) dst=$dst/$dstbase;;
esac
dstdir_status=0
else
dstdir=`dirname "$dst"`
@ -288,6 +291,11 @@ do
fi
fi
case $dstdir in
*/) dstdirslash=$dstdir;;
*) dstdirslash=$dstdir/;;
esac
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
@ -324,14 +332,16 @@ do
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
# $RANDOM is not portable (e.g. dash); use it when possible to
# lower collision chance
# Note that $RANDOM variable is not portable (e.g. dash); Use it
# here however when possible just to lower collision chance.
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
# As "mkdir -p" follows symlinks and we work in /tmp possibly; so
# create the $tmpdir first (and fail if unsuccessful) to make sure
# that nobody tries to guess the $tmpdir name.
# Because "mkdir -p" follows existing symlinks and we likely work
# directly in world-writeable /tmp, make sure that the '$tmpdir'
# directory is successfully created first before we actually test
# 'mkdir -p' feature.
if (umask $mkdir_umask &&
$mkdirprog $mkdir_mode "$tmpdir" &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
@ -434,8 +444,8 @@ do
else
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
dsttmp=${dstdirslash}_inst.$$_
rmtmp=${dstdirslash}_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
@ -500,9 +510,9 @@ do
done
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# eval: (add-hook 'before-save-hook '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:

264
m4/ax_code_coverage.m4 Normal file
View file

@ -0,0 +1,264 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_code_coverage.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_CODE_COVERAGE()
#
# DESCRIPTION
#
# Defines CODE_COVERAGE_CPPFLAGS, CODE_COVERAGE_CFLAGS,
# CODE_COVERAGE_CXXFLAGS and CODE_COVERAGE_LIBS which should be included
# in the CPPFLAGS, CFLAGS CXXFLAGS and LIBS/LIBADD variables of every
# build target (program or library) which should be built with code
# coverage support. Also defines CODE_COVERAGE_RULES which should be
# substituted in your Makefile; and $enable_code_coverage which can be
# used in subsequent configure output. CODE_COVERAGE_ENABLED is defined
# and substituted, and corresponds to the value of the
# --enable-code-coverage option, which defaults to being disabled.
#
# Test also for gcov program and create GCOV variable that could be
# substituted.
#
# Note that all optimisation flags in CFLAGS must be disabled when code
# coverage is enabled.
#
# Usage example:
#
# configure.ac:
#
# AX_CODE_COVERAGE
#
# Makefile.am:
#
# @CODE_COVERAGE_RULES@
# my_program_LIBS = ... $(CODE_COVERAGE_LIBS) ...
# my_program_CPPFLAGS = ... $(CODE_COVERAGE_CPPFLAGS) ...
# my_program_CFLAGS = ... $(CODE_COVERAGE_CFLAGS) ...
# my_program_CXXFLAGS = ... $(CODE_COVERAGE_CXXFLAGS) ...
#
# This results in a "check-code-coverage" rule being added to any
# Makefile.am which includes "@CODE_COVERAGE_RULES@" (assuming the module
# has been configured with --enable-code-coverage). Running `make
# check-code-coverage` in that directory will run the module's test suite
# (`make check`) and build a code coverage report detailing the code which
# was touched, then print the URI for the report.
#
# In earlier versions of this macro, CODE_COVERAGE_LDFLAGS was defined
# instead of CODE_COVERAGE_LIBS. They are both still defined, but use of
# CODE_COVERAGE_LIBS is preferred for clarity; CODE_COVERAGE_LDFLAGS is
# deprecated. They have the same value.
#
# This code was derived from Makefile.decl in GLib, originally licenced
# under LGPLv2.1+.
#
# LICENSE
#
# Copyright (c) 2012, 2016 Philip Withnall
# Copyright (c) 2012 Xan Lopez
# Copyright (c) 2012 Christian Persch
# Copyright (c) 2012 Paolo Borelli
# Copyright (c) 2012 Dan Winship
# Copyright (c) 2015 Bastien ROUCARIES
#
# This library is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or (at
# your option) any later version.
#
# This library 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 Lesser
# General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#serial 21
AC_DEFUN([AX_CODE_COVERAGE],[
dnl Check for --enable-code-coverage
AC_REQUIRE([AC_PROG_SED])
# allow to override gcov location
AC_ARG_WITH([gcov],
[AS_HELP_STRING([--with-gcov[=GCOV]], [use given GCOV for coverage (GCOV=gcov).])],
[_AX_CODE_COVERAGE_GCOV_PROG_WITH=$with_gcov],
[_AX_CODE_COVERAGE_GCOV_PROG_WITH=gcov])
AC_MSG_CHECKING([whether to build with code coverage support])
AC_ARG_ENABLE([code-coverage],
AS_HELP_STRING([--enable-code-coverage],
[Whether to enable code coverage support]),,
enable_code_coverage=no)
AM_CONDITIONAL([CODE_COVERAGE_ENABLED], [test x$enable_code_coverage = xyes])
AC_SUBST([CODE_COVERAGE_ENABLED], [$enable_code_coverage])
AC_MSG_RESULT($enable_code_coverage)
AS_IF([ test "$enable_code_coverage" = "yes" ], [
# check for gcov
AC_CHECK_TOOL([GCOV],
[$_AX_CODE_COVERAGE_GCOV_PROG_WITH],
[:])
AS_IF([test "X$GCOV" = "X:"],
[AC_MSG_ERROR([gcov is needed to do coverage])])
AC_SUBST([GCOV])
dnl Check if gcc is being used
AS_IF([ test "$GCC" = "no" ], [
AC_MSG_ERROR([not compiling with gcc, which is required for gcov code coverage])
])
AC_CHECK_PROG([LCOV], [lcov], [lcov])
AC_CHECK_PROG([GENHTML], [genhtml], [genhtml])
AS_IF([ test -z "$LCOV" ], [
AC_MSG_ERROR([To enable code coverage reporting you must have lcov installed])
])
AS_IF([ test -z "$GENHTML" ], [
AC_MSG_ERROR([Could not find genhtml from the lcov package])
])
dnl Build the code coverage flags
dnl Define CODE_COVERAGE_LDFLAGS for backwards compatibility
CODE_COVERAGE_CPPFLAGS="-DNDEBUG"
CODE_COVERAGE_CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage"
CODE_COVERAGE_CXXFLAGS="-O0 -g -fprofile-arcs -ftest-coverage"
CODE_COVERAGE_LIBS="-lgcov"
CODE_COVERAGE_LDFLAGS="$CODE_COVERAGE_LIBS"
AC_SUBST([CODE_COVERAGE_CPPFLAGS])
AC_SUBST([CODE_COVERAGE_CFLAGS])
AC_SUBST([CODE_COVERAGE_CXXFLAGS])
AC_SUBST([CODE_COVERAGE_LIBS])
AC_SUBST([CODE_COVERAGE_LDFLAGS])
[CODE_COVERAGE_RULES_CHECK='
-$(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) -k check
$(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) code-coverage-capture
']
[CODE_COVERAGE_RULES_CAPTURE='
$(code_coverage_v_lcov_cap)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --capture --output-file "$(CODE_COVERAGE_OUTPUT_FILE).tmp" --test-name "$(call code_coverage_sanitize,$(PACKAGE_NAME)-$(PACKAGE_VERSION))" --no-checksum --compat-libtool $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_OPTIONS)
$(code_coverage_v_lcov_ign)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --remove "$(CODE_COVERAGE_OUTPUT_FILE).tmp" "/tmp/*" $(CODE_COVERAGE_IGNORE_PATTERN) --output-file "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_RMOPTS)
-@rm -f $(CODE_COVERAGE_OUTPUT_FILE).tmp
$(code_coverage_v_genhtml)LANG=C $(GENHTML) $(code_coverage_quiet) $(addprefix --prefix ,$(CODE_COVERAGE_DIRECTORY)) --output-directory "$(CODE_COVERAGE_OUTPUT_DIRECTORY)" --title "$(PACKAGE_NAME)-$(PACKAGE_VERSION) Code Coverage" --legend --show-details "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_GENHTML_OPTIONS)
@echo "file://$(abs_builddir)/$(CODE_COVERAGE_OUTPUT_DIRECTORY)/index.html"
']
[CODE_COVERAGE_RULES_CLEAN='
clean: code-coverage-clean
distclean: code-coverage-clean
code-coverage-clean:
-$(LCOV) --directory $(top_builddir) -z
-rm -rf $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_FILE).tmp $(CODE_COVERAGE_OUTPUT_DIRECTORY)
-find . \( -name "*.gcda" -o -name "*.gcno" -o -name "*.gcov" \) -delete
']
], [
[CODE_COVERAGE_RULES_CHECK='
@echo "Need to reconfigure with --enable-code-coverage"
']
CODE_COVERAGE_RULES_CAPTURE="$CODE_COVERAGE_RULES_CHECK"
CODE_COVERAGE_RULES_CLEAN=''
])
[CODE_COVERAGE_RULES='
# Code coverage
#
# Optional:
# - CODE_COVERAGE_DIRECTORY: Top-level directory for code coverage reporting.
# Multiple directories may be specified, separated by whitespace.
# (Default: $(top_builddir))
# - CODE_COVERAGE_OUTPUT_FILE: Filename and path for the .info file generated
# by lcov for code coverage. (Default:
# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info)
# - CODE_COVERAGE_OUTPUT_DIRECTORY: Directory for generated code coverage
# reports to be created. (Default:
# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage)
# - CODE_COVERAGE_BRANCH_COVERAGE: Set to 1 to enforce branch coverage,
# set to 0 to disable it and leave empty to stay with the default.
# (Default: empty)
# - CODE_COVERAGE_LCOV_SHOPTS_DEFAULT: Extra options shared between both lcov
# instances. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE)
# - CODE_COVERAGE_LCOV_SHOPTS: Extra options to shared between both lcov
# instances. (Default: $CODE_COVERAGE_LCOV_SHOPTS_DEFAULT)
# - CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH: --gcov-tool pathtogcov
# - CODE_COVERAGE_LCOV_OPTIONS_DEFAULT: Extra options to pass to the
# collecting lcov instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH)
# - CODE_COVERAGE_LCOV_OPTIONS: Extra options to pass to the collecting lcov
# instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_DEFAULT)
# - CODE_COVERAGE_LCOV_RMOPTS_DEFAULT: Extra options to pass to the filtering
# lcov instance. (Default: empty)
# - CODE_COVERAGE_LCOV_RMOPTS: Extra options to pass to the filtering lcov
# instance. (Default: $CODE_COVERAGE_LCOV_RMOPTS_DEFAULT)
# - CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT: Extra options to pass to the
# genhtml instance. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE)
# - CODE_COVERAGE_GENHTML_OPTIONS: Extra options to pass to the genhtml
# instance. (Default: $CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT)
# - CODE_COVERAGE_IGNORE_PATTERN: Extra glob pattern of files to ignore
#
# The generated report will be titled using the $(PACKAGE_NAME) and
# $(PACKAGE_VERSION). In order to add the current git hash to the title,
# use the git-version-gen script, available online.
# Optional variables
CODE_COVERAGE_DIRECTORY ?= $(top_builddir)
CODE_COVERAGE_OUTPUT_FILE ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info
CODE_COVERAGE_OUTPUT_DIRECTORY ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage
CODE_COVERAGE_BRANCH_COVERAGE ?=
CODE_COVERAGE_LCOV_SHOPTS_DEFAULT ?= $(if $(CODE_COVERAGE_BRANCH_COVERAGE),\
--rc lcov_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE))
CODE_COVERAGE_LCOV_SHOPTS ?= $(CODE_COVERAGE_LCOV_SHOPTS_DEFAULT)
CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH ?= --gcov-tool "$(GCOV)"
CODE_COVERAGE_LCOV_OPTIONS_DEFAULT ?= $(CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH)
CODE_COVERAGE_LCOV_OPTIONS ?= $(CODE_COVERAGE_LCOV_OPTIONS_DEFAULT)
CODE_COVERAGE_LCOV_RMOPTS_DEFAULT ?=
CODE_COVERAGE_LCOV_RMOPTS ?= $(CODE_COVERAGE_LCOV_RMOPTS_DEFAULT)
CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT ?=\
$(if $(CODE_COVERAGE_BRANCH_COVERAGE),\
--rc genhtml_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE))
CODE_COVERAGE_GENHTML_OPTIONS ?= $(CODE_COVERAGE_GENHTML_OPTIONS_DEFAULTS)
CODE_COVERAGE_IGNORE_PATTERN ?=
code_coverage_v_lcov_cap = $(code_coverage_v_lcov_cap_$(V))
code_coverage_v_lcov_cap_ = $(code_coverage_v_lcov_cap_$(AM_DEFAULT_VERBOSITY))
code_coverage_v_lcov_cap_0 = @echo " LCOV --capture"\
$(CODE_COVERAGE_OUTPUT_FILE);
code_coverage_v_lcov_ign = $(code_coverage_v_lcov_ign_$(V))
code_coverage_v_lcov_ign_ = $(code_coverage_v_lcov_ign_$(AM_DEFAULT_VERBOSITY))
code_coverage_v_lcov_ign_0 = @echo " LCOV --remove /tmp/*"\
$(CODE_COVERAGE_IGNORE_PATTERN);
code_coverage_v_genhtml = $(code_coverage_v_genhtml_$(V))
code_coverage_v_genhtml_ = $(code_coverage_v_genhtml_$(AM_DEFAULT_VERBOSITY))
code_coverage_v_genhtml_0 = @echo " GEN " $(CODE_COVERAGE_OUTPUT_DIRECTORY);
code_coverage_quiet = $(code_coverage_quiet_$(V))
code_coverage_quiet_ = $(code_coverage_quiet_$(AM_DEFAULT_VERBOSITY))
code_coverage_quiet_0 = --quiet
# sanitizes the test-name: replaces with underscores: dashes and dots
code_coverage_sanitize = $(subst -,_,$(subst .,_,$(1)))
# Use recursive makes in order to ignore errors during check
check-code-coverage:'"$CODE_COVERAGE_RULES_CHECK"'
# Capture code coverage data
code-coverage-capture: code-coverage-capture-hook'"$CODE_COVERAGE_RULES_CAPTURE"'
# Hook rule executed before code-coverage-capture, overridable by the user
code-coverage-capture-hook:
'"$CODE_COVERAGE_RULES_CLEAN"'
GITIGNOREFILES ?=
GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY)
A''M_DISTCHECK_CONFIGURE_FLAGS ?=
A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-code-coverage
.PHONY: check-code-coverage code-coverage-capture code-coverage-capture-hook code-coverage-clean
']
AC_SUBST([CODE_COVERAGE_RULES])
m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([CODE_COVERAGE_RULES])])
])

View file

@ -32,7 +32,7 @@ AC_DEFUN([tinc_CURSES],
)
AC_CHECK_LIB(ncurses, initscr,
[CURSES_LIBS="-lncurses"],
[CURSES_LIBS="-lncurses"; AC_CHECK_LIB(tinfo, wtimeout, [CURSES_LIBS+=" -ltinfo"], [])],
[AC_CHECK_LIB(curses, initscr,
[CURSES_LIBS="-lcurses"],
[AC_MSG_ERROR("curses libraries not found.")]

View file

@ -49,10 +49,11 @@ 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 EVP_aes_256_cfb], ,
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>]
)
AC_CHECK_FUNCS([BN_GENCB_new ERR_remove_state RSA_set0_key], , , [#include <openssl/rsa.h>])
AC_CHECK_FUNCS([HMAC_CTX_new], , , [#include <openssl/hmac.h>])
])

16
missing
View file

@ -1,9 +1,9 @@
#! /bin/sh
# Common wrapper for a few potentially missing GNU programs.
scriptversion=2013-10-28.13; # UTC
scriptversion=2018-03-07.03; # UTC
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
# Copyright (C) 1996-2018 Free Software Foundation, Inc.
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
@ -17,7 +17,7 @@ scriptversion=2013-10-28.13; # UTC
# 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, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@ -101,9 +101,9 @@ else
exit $st
fi
perl_URL=http://www.perl.org/
flex_URL=http://flex.sourceforge.net/
gnu_software_URL=http://www.gnu.org/software
perl_URL=https://www.perl.org/
flex_URL=https://github.com/westes/flex
gnu_software_URL=https://www.gnu.org/software
program_details ()
{
@ -207,9 +207,9 @@ give_advice "$1" | sed -e '1s/^/WARNING: /' \
exit $st
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# eval: (add-hook 'before-save-hook '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

@ -42,6 +42,7 @@ chacha_poly1305_SOURCES = \
chacha-poly1305/poly1305.c chacha-poly1305/poly1305.h
tincd_SOURCES = \
address_cache.c address_cache.h \
autoconnect.c autoconnect.h \
buffer.c buffer.h \
cipher.h \
@ -278,10 +279,11 @@ endif
tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS)
sptps_speed_LDADD = -lrt
LIBS = @LIBS@ -lm
LIBS = @LIBS@ -lm $(CODE_COVERAGE_LIBS)
if TUNEMU
LIBS += -lpcap
endif
AM_CFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DSBINDIR=\"$(sbindir)\" -iquote.
AM_CFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DRUNSTATEDIR=\"$(runstatedir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DSBINDIR=\"$(sbindir)\" -iquote. $(CODE_COVERAGE_CFLAGS)
AM_CPPFLAGS = $(CODE_COVERAGE_CPPFLAGS)

View file

@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.15.1 from Makefile.am.
# Makefile.in generated by automake 1.16.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2017 Free Software Foundation, Inc.
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -202,6 +202,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
$(top_srcdir)/m4/ax_cflags_warn_all.m4 \
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
$(top_srcdir)/m4/ax_check_link_flag.m4 \
$(top_srcdir)/m4/ax_code_coverage.m4 \
$(top_srcdir)/m4/ax_require_defined.m4 \
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \
$(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \
@ -336,22 +337,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 = 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 \
am__tincd_SOURCES_DIST = address_cache.c address_cache.h 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 \
@ -384,15 +386,15 @@ am__tincd_SOURCES_DIST = autoconnect.c autoconnect.h buffer.c buffer.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 = 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) \
am_tincd_OBJECTS = address_cache.$(OBJEXT) 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) \
@ -423,7 +425,54 @@ am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES =
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__maybe_remake_depfiles = depfiles
am__depfiles_remade = ./$(DEPDIR)/address_cache.Po \
./$(DEPDIR)/autoconnect.Po ./$(DEPDIR)/buffer.Po \
./$(DEPDIR)/conf.Po ./$(DEPDIR)/connection.Po \
./$(DEPDIR)/control.Po ./$(DEPDIR)/dropin.Po \
./$(DEPDIR)/dummy_device.Po ./$(DEPDIR)/edge.Po \
./$(DEPDIR)/event.Po ./$(DEPDIR)/fd_device.Po \
./$(DEPDIR)/fsck.Po ./$(DEPDIR)/getopt.Po \
./$(DEPDIR)/getopt1.Po ./$(DEPDIR)/graph.Po \
./$(DEPDIR)/hash.Po ./$(DEPDIR)/ifconfig.Po \
./$(DEPDIR)/info.Po ./$(DEPDIR)/invitation.Po \
./$(DEPDIR)/list.Po ./$(DEPDIR)/logger.Po ./$(DEPDIR)/meta.Po \
./$(DEPDIR)/multicast_device.Po ./$(DEPDIR)/names.Po \
./$(DEPDIR)/net.Po ./$(DEPDIR)/net_packet.Po \
./$(DEPDIR)/net_setup.Po ./$(DEPDIR)/net_socket.Po \
./$(DEPDIR)/netutl.Po ./$(DEPDIR)/node.Po \
./$(DEPDIR)/process.Po ./$(DEPDIR)/protocol.Po \
./$(DEPDIR)/protocol_auth.Po ./$(DEPDIR)/protocol_edge.Po \
./$(DEPDIR)/protocol_key.Po ./$(DEPDIR)/protocol_misc.Po \
./$(DEPDIR)/protocol_subnet.Po \
./$(DEPDIR)/raw_socket_device.Po ./$(DEPDIR)/route.Po \
./$(DEPDIR)/script.Po ./$(DEPDIR)/splay_tree.Po \
./$(DEPDIR)/sptps.Po ./$(DEPDIR)/sptps_keypair.Po \
./$(DEPDIR)/sptps_speed.Po ./$(DEPDIR)/sptps_test.Po \
./$(DEPDIR)/subnet.Po ./$(DEPDIR)/subnet_parse.Po \
./$(DEPDIR)/tincctl.Po ./$(DEPDIR)/tincd.Po ./$(DEPDIR)/top.Po \
./$(DEPDIR)/uml_device.Po ./$(DEPDIR)/upnp.Po \
./$(DEPDIR)/utils.Po ./$(DEPDIR)/vde_device.Po \
./$(DEPDIR)/version.Po bsd/$(DEPDIR)/device.Po \
bsd/$(DEPDIR)/tunemu.Po \
chacha-poly1305/$(DEPDIR)/chacha-poly1305.Po \
chacha-poly1305/$(DEPDIR)/chacha.Po \
chacha-poly1305/$(DEPDIR)/poly1305.Po \
cygwin/$(DEPDIR)/device.Po ed25519/$(DEPDIR)/ecdh.Po \
ed25519/$(DEPDIR)/ecdsa.Po ed25519/$(DEPDIR)/ecdsagen.Po \
ed25519/$(DEPDIR)/fe.Po ed25519/$(DEPDIR)/ge.Po \
ed25519/$(DEPDIR)/key_exchange.Po ed25519/$(DEPDIR)/keypair.Po \
ed25519/$(DEPDIR)/sc.Po ed25519/$(DEPDIR)/sha512.Po \
ed25519/$(DEPDIR)/sign.Po ed25519/$(DEPDIR)/verify.Po \
gcrypt/$(DEPDIR)/cipher.Po gcrypt/$(DEPDIR)/crypto.Po \
gcrypt/$(DEPDIR)/digest.Po gcrypt/$(DEPDIR)/prf.Po \
gcrypt/$(DEPDIR)/rsa.Po gcrypt/$(DEPDIR)/rsagen.Po \
linux/$(DEPDIR)/device.Po mingw/$(DEPDIR)/device.Po \
nolegacy/$(DEPDIR)/crypto.Po nolegacy/$(DEPDIR)/prf.Po \
openssl/$(DEPDIR)/cipher.Po openssl/$(DEPDIR)/crypto.Po \
openssl/$(DEPDIR)/digest.Po openssl/$(DEPDIR)/prf.Po \
openssl/$(DEPDIR)/rsa.Po openssl/$(DEPDIR)/rsagen.Po \
solaris/$(DEPDIR)/device.Po
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@ -478,6 +527,12 @@ AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@
CODE_COVERAGE_CPPFLAGS = @CODE_COVERAGE_CPPFLAGS@
CODE_COVERAGE_CXXFLAGS = @CODE_COVERAGE_CXXFLAGS@
CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@
CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@
CODE_COVERAGE_LIBS = @CODE_COVERAGE_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CURSES_LIBS = @CURSES_LIBS@
@ -489,16 +544,18 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GCOV = @GCOV@
GENHTML = @GENHTML@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LCOV = @LCOV@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@ -lm $(am__append_30)
LN_S = @LN_S@
LIBS = @LIBS@ -lm $(CODE_COVERAGE_LIBS) $(am__append_30)
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MINIUPNPC_LIBS = @MINIUPNPC_LIBS@
@ -513,6 +570,7 @@ PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
READLINE_LIBS = @READLINE_LIBS@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
@ -588,16 +646,17 @@ chacha_poly1305_SOURCES = \
chacha-poly1305/chacha-poly1305.c chacha-poly1305/chacha-poly1305.h \
chacha-poly1305/poly1305.c chacha-poly1305/poly1305.h
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 \
tincd_SOURCES = address_cache.c address_cache.h 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 \
@ -632,7 +691,8 @@ sptps_speed_SOURCES = logger.c logger.h sptps.c sptps.h sptps_speed.c \
@MINIUPNPC_TRUE@tincd_LDFLAGS = -pthread
tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS)
sptps_speed_LDADD = -lrt
AM_CFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DSBINDIR=\"$(sbindir)\" -iquote.
AM_CFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DRUNSTATEDIR=\"$(runstatedir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DSBINDIR=\"$(sbindir)\" -iquote. $(CODE_COVERAGE_CFLAGS)
AM_CPPFLAGS = $(CODE_COVERAGE_CPPFLAGS)
all: all-am
.SUFFIXES:
@ -654,8 +714,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@ -893,94 +953,101 @@ 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@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/control.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dropin.Po@am__quote@
@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@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/graph.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ifconfig.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/info.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/invitation.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logger.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meta.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/multicast_device.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/names.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_packet.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_setup.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_socket.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netutl.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/node.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_auth.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_edge.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_key.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_misc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_subnet.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/raw_socket_device.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/route.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/script.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/splay_tree.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_keypair.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_speed.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_test.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subnet.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subnet_parse.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tincctl.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tincd.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/top.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uml_device.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upnp.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vde_device.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@bsd/$(DEPDIR)/device.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@bsd/$(DEPDIR)/tunemu.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/chacha-poly1305.Po@am__quote@
@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)/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@
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/fe.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ge.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/key_exchange.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/keypair.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/sc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/sha512.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/sign.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/verify.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/cipher.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/crypto.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/digest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/prf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/rsa.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/rsagen.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@linux/$(DEPDIR)/device.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@mingw/$(DEPDIR)/device.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@nolegacy/$(DEPDIR)/crypto.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@nolegacy/$(DEPDIR)/prf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/cipher.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/crypto.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/digest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/prf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/rsa.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/rsagen.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@solaris/$(DEPDIR)/device.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/address_cache.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/autoconnect.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buffer.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conf.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connection.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/control.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dropin.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy_device.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edge.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fd_device.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsck.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/graph.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ifconfig.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/info.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/invitation.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logger.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meta.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/multicast_device.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/names.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_packet.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_setup.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_socket.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netutl.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/node.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_auth.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_edge.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_key.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_misc.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_subnet.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/raw_socket_device.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/route.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/script.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/splay_tree.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_keypair.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_speed.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_test.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subnet.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subnet_parse.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tincctl.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tincd.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/top.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uml_device.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upnp.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vde_device.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@bsd/$(DEPDIR)/device.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@bsd/$(DEPDIR)/tunemu.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/chacha-poly1305.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/chacha.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/poly1305.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@cygwin/$(DEPDIR)/device.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdh.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdsa.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdsagen.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/fe.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ge.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/key_exchange.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/keypair.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/sc.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/sha512.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/sign.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/verify.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/cipher.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/crypto.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/digest.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/prf.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/rsa.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/rsagen.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@linux/$(DEPDIR)/device.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@mingw/$(DEPDIR)/device.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@nolegacy/$(DEPDIR)/crypto.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@nolegacy/$(DEPDIR)/prf.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/cipher.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/crypto.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/digest.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/prf.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/rsa.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/rsagen.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@solaris/$(DEPDIR)/device.Po@am__quote@ # am--include-marker
$(am__depfiles_remade):
@$(MKDIR_P) $(@D)
@echo '# dummy' >$@-t && $(am__mv) $@-t $@
am--depfiles: $(am__depfiles_remade)
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@ -1050,7 +1117,10 @@ cscopelist-am: $(am__tagged_files)
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
@ -1145,7 +1215,95 @@ 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)
-rm -f ./$(DEPDIR)/address_cache.Po
-rm -f ./$(DEPDIR)/autoconnect.Po
-rm -f ./$(DEPDIR)/buffer.Po
-rm -f ./$(DEPDIR)/conf.Po
-rm -f ./$(DEPDIR)/connection.Po
-rm -f ./$(DEPDIR)/control.Po
-rm -f ./$(DEPDIR)/dropin.Po
-rm -f ./$(DEPDIR)/dummy_device.Po
-rm -f ./$(DEPDIR)/edge.Po
-rm -f ./$(DEPDIR)/event.Po
-rm -f ./$(DEPDIR)/fd_device.Po
-rm -f ./$(DEPDIR)/fsck.Po
-rm -f ./$(DEPDIR)/getopt.Po
-rm -f ./$(DEPDIR)/getopt1.Po
-rm -f ./$(DEPDIR)/graph.Po
-rm -f ./$(DEPDIR)/hash.Po
-rm -f ./$(DEPDIR)/ifconfig.Po
-rm -f ./$(DEPDIR)/info.Po
-rm -f ./$(DEPDIR)/invitation.Po
-rm -f ./$(DEPDIR)/list.Po
-rm -f ./$(DEPDIR)/logger.Po
-rm -f ./$(DEPDIR)/meta.Po
-rm -f ./$(DEPDIR)/multicast_device.Po
-rm -f ./$(DEPDIR)/names.Po
-rm -f ./$(DEPDIR)/net.Po
-rm -f ./$(DEPDIR)/net_packet.Po
-rm -f ./$(DEPDIR)/net_setup.Po
-rm -f ./$(DEPDIR)/net_socket.Po
-rm -f ./$(DEPDIR)/netutl.Po
-rm -f ./$(DEPDIR)/node.Po
-rm -f ./$(DEPDIR)/process.Po
-rm -f ./$(DEPDIR)/protocol.Po
-rm -f ./$(DEPDIR)/protocol_auth.Po
-rm -f ./$(DEPDIR)/protocol_edge.Po
-rm -f ./$(DEPDIR)/protocol_key.Po
-rm -f ./$(DEPDIR)/protocol_misc.Po
-rm -f ./$(DEPDIR)/protocol_subnet.Po
-rm -f ./$(DEPDIR)/raw_socket_device.Po
-rm -f ./$(DEPDIR)/route.Po
-rm -f ./$(DEPDIR)/script.Po
-rm -f ./$(DEPDIR)/splay_tree.Po
-rm -f ./$(DEPDIR)/sptps.Po
-rm -f ./$(DEPDIR)/sptps_keypair.Po
-rm -f ./$(DEPDIR)/sptps_speed.Po
-rm -f ./$(DEPDIR)/sptps_test.Po
-rm -f ./$(DEPDIR)/subnet.Po
-rm -f ./$(DEPDIR)/subnet_parse.Po
-rm -f ./$(DEPDIR)/tincctl.Po
-rm -f ./$(DEPDIR)/tincd.Po
-rm -f ./$(DEPDIR)/top.Po
-rm -f ./$(DEPDIR)/uml_device.Po
-rm -f ./$(DEPDIR)/upnp.Po
-rm -f ./$(DEPDIR)/utils.Po
-rm -f ./$(DEPDIR)/vde_device.Po
-rm -f ./$(DEPDIR)/version.Po
-rm -f bsd/$(DEPDIR)/device.Po
-rm -f bsd/$(DEPDIR)/tunemu.Po
-rm -f chacha-poly1305/$(DEPDIR)/chacha-poly1305.Po
-rm -f chacha-poly1305/$(DEPDIR)/chacha.Po
-rm -f chacha-poly1305/$(DEPDIR)/poly1305.Po
-rm -f cygwin/$(DEPDIR)/device.Po
-rm -f ed25519/$(DEPDIR)/ecdh.Po
-rm -f ed25519/$(DEPDIR)/ecdsa.Po
-rm -f ed25519/$(DEPDIR)/ecdsagen.Po
-rm -f ed25519/$(DEPDIR)/fe.Po
-rm -f ed25519/$(DEPDIR)/ge.Po
-rm -f ed25519/$(DEPDIR)/key_exchange.Po
-rm -f ed25519/$(DEPDIR)/keypair.Po
-rm -f ed25519/$(DEPDIR)/sc.Po
-rm -f ed25519/$(DEPDIR)/sha512.Po
-rm -f ed25519/$(DEPDIR)/sign.Po
-rm -f ed25519/$(DEPDIR)/verify.Po
-rm -f gcrypt/$(DEPDIR)/cipher.Po
-rm -f gcrypt/$(DEPDIR)/crypto.Po
-rm -f gcrypt/$(DEPDIR)/digest.Po
-rm -f gcrypt/$(DEPDIR)/prf.Po
-rm -f gcrypt/$(DEPDIR)/rsa.Po
-rm -f gcrypt/$(DEPDIR)/rsagen.Po
-rm -f linux/$(DEPDIR)/device.Po
-rm -f mingw/$(DEPDIR)/device.Po
-rm -f nolegacy/$(DEPDIR)/crypto.Po
-rm -f nolegacy/$(DEPDIR)/prf.Po
-rm -f openssl/$(DEPDIR)/cipher.Po
-rm -f openssl/$(DEPDIR)/crypto.Po
-rm -f openssl/$(DEPDIR)/digest.Po
-rm -f openssl/$(DEPDIR)/prf.Po
-rm -f openssl/$(DEPDIR)/rsa.Po
-rm -f openssl/$(DEPDIR)/rsagen.Po
-rm -f solaris/$(DEPDIR)/device.Po
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
@ -1191,7 +1349,95 @@ install-ps-am:
installcheck-am: installcheck-sbinPROGRAMS
maintainer-clean: maintainer-clean-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)
-rm -f ./$(DEPDIR)/address_cache.Po
-rm -f ./$(DEPDIR)/autoconnect.Po
-rm -f ./$(DEPDIR)/buffer.Po
-rm -f ./$(DEPDIR)/conf.Po
-rm -f ./$(DEPDIR)/connection.Po
-rm -f ./$(DEPDIR)/control.Po
-rm -f ./$(DEPDIR)/dropin.Po
-rm -f ./$(DEPDIR)/dummy_device.Po
-rm -f ./$(DEPDIR)/edge.Po
-rm -f ./$(DEPDIR)/event.Po
-rm -f ./$(DEPDIR)/fd_device.Po
-rm -f ./$(DEPDIR)/fsck.Po
-rm -f ./$(DEPDIR)/getopt.Po
-rm -f ./$(DEPDIR)/getopt1.Po
-rm -f ./$(DEPDIR)/graph.Po
-rm -f ./$(DEPDIR)/hash.Po
-rm -f ./$(DEPDIR)/ifconfig.Po
-rm -f ./$(DEPDIR)/info.Po
-rm -f ./$(DEPDIR)/invitation.Po
-rm -f ./$(DEPDIR)/list.Po
-rm -f ./$(DEPDIR)/logger.Po
-rm -f ./$(DEPDIR)/meta.Po
-rm -f ./$(DEPDIR)/multicast_device.Po
-rm -f ./$(DEPDIR)/names.Po
-rm -f ./$(DEPDIR)/net.Po
-rm -f ./$(DEPDIR)/net_packet.Po
-rm -f ./$(DEPDIR)/net_setup.Po
-rm -f ./$(DEPDIR)/net_socket.Po
-rm -f ./$(DEPDIR)/netutl.Po
-rm -f ./$(DEPDIR)/node.Po
-rm -f ./$(DEPDIR)/process.Po
-rm -f ./$(DEPDIR)/protocol.Po
-rm -f ./$(DEPDIR)/protocol_auth.Po
-rm -f ./$(DEPDIR)/protocol_edge.Po
-rm -f ./$(DEPDIR)/protocol_key.Po
-rm -f ./$(DEPDIR)/protocol_misc.Po
-rm -f ./$(DEPDIR)/protocol_subnet.Po
-rm -f ./$(DEPDIR)/raw_socket_device.Po
-rm -f ./$(DEPDIR)/route.Po
-rm -f ./$(DEPDIR)/script.Po
-rm -f ./$(DEPDIR)/splay_tree.Po
-rm -f ./$(DEPDIR)/sptps.Po
-rm -f ./$(DEPDIR)/sptps_keypair.Po
-rm -f ./$(DEPDIR)/sptps_speed.Po
-rm -f ./$(DEPDIR)/sptps_test.Po
-rm -f ./$(DEPDIR)/subnet.Po
-rm -f ./$(DEPDIR)/subnet_parse.Po
-rm -f ./$(DEPDIR)/tincctl.Po
-rm -f ./$(DEPDIR)/tincd.Po
-rm -f ./$(DEPDIR)/top.Po
-rm -f ./$(DEPDIR)/uml_device.Po
-rm -f ./$(DEPDIR)/upnp.Po
-rm -f ./$(DEPDIR)/utils.Po
-rm -f ./$(DEPDIR)/vde_device.Po
-rm -f ./$(DEPDIR)/version.Po
-rm -f bsd/$(DEPDIR)/device.Po
-rm -f bsd/$(DEPDIR)/tunemu.Po
-rm -f chacha-poly1305/$(DEPDIR)/chacha-poly1305.Po
-rm -f chacha-poly1305/$(DEPDIR)/chacha.Po
-rm -f chacha-poly1305/$(DEPDIR)/poly1305.Po
-rm -f cygwin/$(DEPDIR)/device.Po
-rm -f ed25519/$(DEPDIR)/ecdh.Po
-rm -f ed25519/$(DEPDIR)/ecdsa.Po
-rm -f ed25519/$(DEPDIR)/ecdsagen.Po
-rm -f ed25519/$(DEPDIR)/fe.Po
-rm -f ed25519/$(DEPDIR)/ge.Po
-rm -f ed25519/$(DEPDIR)/key_exchange.Po
-rm -f ed25519/$(DEPDIR)/keypair.Po
-rm -f ed25519/$(DEPDIR)/sc.Po
-rm -f ed25519/$(DEPDIR)/sha512.Po
-rm -f ed25519/$(DEPDIR)/sign.Po
-rm -f ed25519/$(DEPDIR)/verify.Po
-rm -f gcrypt/$(DEPDIR)/cipher.Po
-rm -f gcrypt/$(DEPDIR)/crypto.Po
-rm -f gcrypt/$(DEPDIR)/digest.Po
-rm -f gcrypt/$(DEPDIR)/prf.Po
-rm -f gcrypt/$(DEPDIR)/rsa.Po
-rm -f gcrypt/$(DEPDIR)/rsagen.Po
-rm -f linux/$(DEPDIR)/device.Po
-rm -f mingw/$(DEPDIR)/device.Po
-rm -f nolegacy/$(DEPDIR)/crypto.Po
-rm -f nolegacy/$(DEPDIR)/prf.Po
-rm -f openssl/$(DEPDIR)/cipher.Po
-rm -f openssl/$(DEPDIR)/crypto.Po
-rm -f openssl/$(DEPDIR)/digest.Po
-rm -f openssl/$(DEPDIR)/prf.Po
-rm -f openssl/$(DEPDIR)/rsa.Po
-rm -f openssl/$(DEPDIR)/rsagen.Po
-rm -f solaris/$(DEPDIR)/device.Po
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
@ -1211,7 +1457,7 @@ uninstall-am: uninstall-sbinPROGRAMS
.MAKE: check-am install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \
.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles 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 \

277
src/address_cache.c Normal file
View file

@ -0,0 +1,277 @@
/*
address_cache.c -- Manage cache of recently seen addresses
Copyright (C) 2018 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 "address_cache.h"
#include "conf.h"
#include "names.h"
#include "netutl.h"
#include "xalloc.h"
static const unsigned int NOT_CACHED = -1;
// 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) {
continue;
}
bool found = false;
for(struct addrinfo *aip = ai; aip; aip = aip->ai_next) {
if(!sockaddrcmp(&e->reverse->address, (sockaddr_t *)aip->ai_addr)) {
found = true;
break;
}
}
if(found) {
continue;
}
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;
}
static void free_known_addresses(struct addrinfo *ai) {
for(struct addrinfo *aip = ai, *next; aip; aip = next) {
next = aip->ai_next;
free(aip);
}
}
static unsigned int find_cached(address_cache_t *cache, const sockaddr_t *sa) {
for(unsigned int i = 0; i < cache->data.used; i++)
if(!sockaddrcmp(&cache->data.address[i], sa)) {
return i;
}
return NOT_CACHED;
}
void add_recent_address(address_cache_t *cache, const sockaddr_t *sa) {
// Check if it's already cached
unsigned int pos = find_cached(cache, sa);
// It's in the first spot, so nothing to do
if(pos == 0) {
return;
}
// Shift everything, move/add the address to the first slot
if(pos == NOT_CACHED) {
if(cache->data.used < MAX_CACHED_ADDRESSES) {
cache->data.used++;
}
pos = cache->data.used - 1;
}
memmove(&cache->data.address[1], &cache->data.address[0], pos * sizeof(cache->data.address[0]));
cache->data.address[0] = *sa;
// Write the cache
char fname[PATH_MAX];
snprintf(fname, sizeof(fname), "%s" SLASH "cache" SLASH "%s", confbase, cache->node->name);
FILE *fp = fopen(fname, "wb");
if(fp) {
fwrite(&cache->data, sizeof(cache->data), 1, fp);
fclose(fp);
}
}
const sockaddr_t *get_recent_address(address_cache_t *cache) {
// Check if there is an address in our cache of recently seen addresses
if(cache->tried < cache->data.used) {
return &cache->data.address[cache->tried++];
}
// Next, check any recently seen addresses not in our cache
while(cache->tried == cache->data.used) {
if(!cache->ai) {
cache->aip = cache->ai = get_known_addresses(cache->node);
}
if(cache->ai) {
if(cache->aip) {
sockaddr_t *sa = (sockaddr_t *)cache->aip->ai_addr;
cache->aip = cache->aip->ai_next;
if(find_cached(cache, sa) != NOT_CACHED) {
continue;
}
return sa;
} else {
free_known_addresses(cache->ai);
cache->ai = NULL;
}
}
cache->tried++;
}
// Otherwise, check if there are any known Address statements
if(!cache->config_tree) {
init_configuration(&cache->config_tree);
read_host_config(cache->config_tree, cache->node->name, false);
cache->cfg = lookup_config(cache->config_tree, "Address");
}
while(cache->cfg && !cache->ai) {
char *address, *port;
get_config_string(cache->cfg, &address);
char *space = strchr(address, ' ');
if(space) {
port = xstrdup(space + 1);
*space = 0;
} else {
if(!get_config_string(lookup_config(cache->config_tree, "Port"), &port)) {
port = xstrdup("655");
}
}
cache->aip = cache->ai = str2addrinfo(address, port, SOCK_STREAM);
if(cache->ai) {
struct addrinfo *ai = NULL;
for(; cache->aip; cache->aip = cache->aip->ai_next) {
struct addrinfo *oai = ai;
ai = xzalloc(sizeof(*ai));
ai->ai_family = cache->aip->ai_family;
ai->ai_socktype = cache->aip->ai_socktype;
ai->ai_protocol = cache->aip->ai_protocol;
ai->ai_addrlen = cache->aip->ai_addrlen;
ai->ai_addr = xmalloc(ai->ai_addrlen);
memcpy(ai->ai_addr, cache->aip->ai_addr, ai->ai_addrlen);
ai->ai_next = oai;
}
freeaddrinfo(cache->ai);
cache->aip = cache->ai = ai;
}
free(address);
free(port);
cache->cfg = lookup_config_next(cache->config_tree, cache->cfg);
}
if(cache->ai) {
if(cache->aip) {
sockaddr_t *sa = (sockaddr_t *)cache->aip->ai_addr;
cache->aip = cache->aip->ai_next;
return sa;
} else {
free_known_addresses(cache->ai);
cache->ai = NULL;
}
}
// We're all out of addresses.
exit_configuration(&cache->config_tree);
return false;
}
address_cache_t *open_address_cache(node_t *node) {
address_cache_t *cache = xmalloc(sizeof(*cache));
cache->node = node;
// Try to open an existing address cache
char fname[PATH_MAX];
snprintf(fname, sizeof(fname), "%s" SLASH "cache" SLASH "%s", confbase, node->name);
FILE *fp = fopen(fname, "rb");
if(!fp || fread(&cache->data, sizeof(cache->data), 1, fp) != 1 || cache->data.version != ADDRESS_CACHE_VERSION) {
memset(&cache->data, 0, sizeof(cache->data));
}
if(fp) {
fclose(fp);
}
// Ensure we have a valid state
cache->config_tree = NULL;
cache->cfg = NULL;
cache->ai = NULL;
cache->aip = NULL;
cache->tried = 0;
cache->data.version = ADDRESS_CACHE_VERSION;
if(cache->data.used > MAX_CACHED_ADDRESSES) {
cache->data.used = 0;
}
return cache;
}
void reset_address_cache(address_cache_t *cache, const sockaddr_t *sa) {
if(sa) {
add_recent_address(cache, sa);
}
if(cache->config_tree) {
exit_configuration(&cache->config_tree);
}
if(cache->ai) {
free_known_addresses(cache->ai);
}
cache->config_tree = NULL;
cache->cfg = NULL;
cache->ai = NULL;
cache->aip = NULL;
cache->tried = 0;
}
void close_address_cache(address_cache_t *cache) {
if(cache->config_tree) {
exit_configuration(&cache->config_tree);
}
if(cache->ai) {
free_known_addresses(cache->ai);
}
free(cache);
}

50
src/address_cache.h Normal file
View file

@ -0,0 +1,50 @@
#ifndef TINC_ADDRESS_CACHE_H
#define TINC_ADDRESS_CACHE_H
/*
address_cache.h -- header for address_cache.c
Copyright (C) 2018 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 "net.h"
#define MAX_CACHED_ADDRESSES 8
#define ADDRESS_CACHE_VERSION 1
typedef struct address_cache_t {
struct node_t *node;
struct splay_tree_t *config_tree;
struct config_t *cfg;
struct addrinfo *ai;
struct addrinfo *aip;
unsigned int tried;
struct {
unsigned int version;
unsigned int used;
sockaddr_t address[MAX_CACHED_ADDRESSES];
} data;
} address_cache_t;
void add_recent_address(address_cache_t *cache, const sockaddr_t *sa);
const sockaddr_t *get_recent_address(address_cache_t *cache);
address_cache_t *open_address_cache(struct node_t *node);
void reset_address_cache(address_cache_t *cache, const sockaddr_t *sa);
void close_address_cache(address_cache_t *cache);
#endif

View file

@ -27,28 +27,34 @@
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))
if(n == myself || n->connection || !(n->status.has_address || n->status.reachable)) {
continue;
}
count++;
}
if(!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))
if(n == myself || n->connection || !(n->status.has_address || n->status.reachable)) {
continue;
}
if(r--)
if(r--) {
continue;
}
bool found = false;
for list_each(outgoing_t, outgoing, outgoing_list) {
if(!strcmp(outgoing->name, n->name)) {
if(outgoing->node == n) {
found = true;
break;
}
@ -56,10 +62,10 @@ static void make_new_connection() {
if(!found) {
logger(DEBUG_CONNECTIONS, LOG_INFO, "Autoconnecting to %s", n->name);
outgoing_t *outgoing = xzalloc(sizeof *outgoing);
outgoing->name = xstrdup(n->name);
outgoing_t *outgoing = xzalloc(sizeof(*outgoing));
outgoing->node = n;
list_insert_tail(outgoing_list, outgoing);
setup_outgoing_connection(outgoing);
setup_outgoing_connection(outgoing, false);
}
break;
@ -77,23 +83,27 @@ static void connect_to_unreachable() {
int r = rand() % node_tree->count;
for splay_each(node_t, n, node_tree) {
if(r--)
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)
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))
/* Are we already trying to make an outgoing connection to it? If so, return. */
for list_each(outgoing_t, outgoing, outgoing_list) {
if(outgoing->node == n) {
return;
}
}
logger(DEBUG_CONNECTIONS, LOG_INFO, "Autoconnecting to %s", n->name);
outgoing_t *outgoing = xzalloc(sizeof *outgoing);
outgoing->name = xstrdup(n->name);
outgoing_t *outgoing = xzalloc(sizeof(*outgoing));
outgoing->node = n;
list_insert_tail(outgoing_list, outgoing);
setup_outgoing_connection(outgoing);
setup_outgoing_connection(outgoing, false);
return;
}
@ -102,23 +112,29 @@ static void connect_to_unreachable() {
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)
if(!c->edge || !c->outgoing || !c->node || c->node->edge_tree->count < 2) {
continue;
}
count++;
}
if(!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)
if(!c->edge || !c->outgoing || !c->node || c->node->edge_tree->count < 2) {
continue;
}
if(r--)
if(r--) {
continue;
}
logger(DEBUG_CONNECTIONS, LOG_INFO, "Autodisconnecting from %s", c->name);
list_delete(outgoing_list, c->outgoing);
@ -132,6 +148,7 @@ 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;
@ -139,10 +156,11 @@ static void drop_superfluous_pending_connections() {
}
}
if(found)
if(found) {
continue;
}
logger(DEBUG_CONNECTIONS, LOG_INFO, "Cancelled outgoing connection to %s", o->name);
logger(DEBUG_CONNECTIONS, LOG_INFO, "Cancelled outgoing connection to %s", o->node->name);
list_delete_node(outgoing_list, node);
}
}
@ -150,10 +168,12 @@ static void drop_superfluous_pending_connections() {
void do_autoconnect() {
/* Count number of active connections. */
int nc = 0;
for list_each(connection_t, c, connection_list) {
if(c->edge)
if(c->edge) {
nc++;
}
}
/* Less than 3 connections? Eagerly try to make a new one. */
if(nc < 3) {
@ -162,8 +182,9 @@ void do_autoconnect() {
}
/* More than 3 connections? See if we can get rid of a superfluous one. */
if(nc > 3)
if(nc > 3) {
drop_superfluous_outgoing_connection();
}
/* Check if there are unreachable nodes that we should try to connect to. */

View file

@ -1,3 +1,6 @@
#ifndef TINC_AUTOCONNECT_H
#define TINC_AUTOCONNECT_H
/*
autoconnect.h -- header for autoconnect.c
Copyright (C) 2017 Guus Sliepen <guus@tinc-vpn.org>
@ -17,9 +20,6 @@
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

@ -56,7 +56,7 @@ typedef enum device_type {
int device_fd = -1;
char *device = NULL;
char *iface = NULL;
static char *device_info = NULL;
static const char *device_info = "OS X utun device";
#if defined(ENABLE_TUNEMU)
static device_type_t device_type = DEVICE_TYPE_TUNEMU;
#elif defined(HAVE_OPENBSD) || defined(HAVE_FREEBSD) || defined(HAVE_DRAGONFLY)
@ -68,13 +68,15 @@ static device_type_t device_type = DEVICE_TYPE_TUN;
#ifdef HAVE_NET_IF_UTUN_H
static bool setup_utun(void) {
device_fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
if(device_fd == -1) {
logger(DEBUG_ALWAYS, LOG_ERR, "Could not open PF_SYSTEM socket: %s\n", strerror(errno));
return false;
}
struct ctl_info info = {};
strlcpy(info.ctl_name, UTUN_CONTROL_NAME, sizeof info.ctl_name);
strlcpy(info.ctl_name, UTUN_CONTROL_NAME, sizeof(info.ctl_name));
if(ioctl(device_fd, CTLIOCGINFO, &info) == -1) {
logger(DEBUG_ALWAYS, LOG_ERR, "ioctl(CTLIOCGINFO) failed: %s", strerror(errno));
@ -83,15 +85,18 @@ static bool setup_utun(void) {
int unit = -1;
char *p = strstr(device, "utun"), *e = NULL;
if(p) {
unit = strtol(p + 4, &e, 10);
if(!e)
if(!e) {
unit = -1;
}
}
struct sockaddr_ctl sc = {
.sc_id = info.ctl_id,
.sc_len = sizeof sc,
.sc_len = sizeof(sc),
.sc_family = AF_SYSTEM,
.ss_sysaddr = AF_SYS_CONTROL,
.sc_unit = unit + 1,
@ -103,15 +108,14 @@ static bool setup_utun(void) {
}
char name[64] = "";
socklen_t len = sizeof name;
socklen_t len = sizeof(name);
if(getsockopt(device_fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, name, &len)) {
iface = xstrdup(device);
} else {
iface = xstrdup(name);
}
device_info = "OS X utun device";
logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info);
return true;
@ -124,36 +128,44 @@ static bool setup_device(void) {
// Find out if it's supposed to be a tun or a tap device
char *type;
if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) {
if(!strcasecmp(type, "tun"))
/* use default */;
#ifdef ENABLE_TUNEMU
else if(!strcasecmp(type, "tunemu"))
else if(!strcasecmp(type, "tunemu")) {
device_type = DEVICE_TYPE_TUNEMU;
}
#endif
#ifdef HAVE_NET_IF_UTUN_H
else if(!strcasecmp(type, "utun"))
else if(!strcasecmp(type, "utun")) {
device_type = DEVICE_TYPE_UTUN;
}
#endif
else if(!strcasecmp(type, "tunnohead"))
else if(!strcasecmp(type, "tunnohead")) {
device_type = DEVICE_TYPE_TUN;
else if(!strcasecmp(type, "tunifhead"))
} else if(!strcasecmp(type, "tunifhead")) {
device_type = DEVICE_TYPE_TUNIFHEAD;
else if(!strcasecmp(type, "tap"))
} else if(!strcasecmp(type, "tap")) {
device_type = DEVICE_TYPE_TAP;
else {
} else {
logger(DEBUG_ALWAYS, LOG_ERR, "Unknown device type %s!", type);
return false;
}
} else {
#ifdef HAVE_NET_IF_UTUN_H
if(device && (strncmp(device, "utun", 4) == 0 || strncmp(device, "/dev/utun", 9) == 0))
if(device && (strncmp(device, "utun", 4) == 0 || strncmp(device, "/dev/utun", 9) == 0)) {
device_type = DEVICE_TYPE_UTUN;
else
} else
#endif
if((device && strstr(device, "tap")) || routing_mode != RMODE_ROUTER)
if((device && strstr(device, "tap")) || routing_mode != RMODE_ROUTER) {
device_type = DEVICE_TYPE_TAP;
}
}
if(routing_mode == RMODE_SWITCH && device_type != DEVICE_TYPE_TAP) {
logger(DEBUG_ALWAYS, LOG_ERR, "Only tap devices support switch mode!");
@ -163,16 +175,18 @@ static bool setup_device(void) {
// Find out which device file to open
if(!device) {
if(device_type == DEVICE_TYPE_TAP)
if(device_type == DEVICE_TYPE_TAP) {
device = xstrdup(DEFAULT_TAP_DEVICE);
else
} else {
device = xstrdup(DEFAULT_TUN_DEVICE);
}
}
// Open the device
switch(device_type) {
#ifdef ENABLE_TUNEMU
case DEVICE_TYPE_TUNEMU: {
char dynamic_name[256] = "";
device_fd = tunemu_open(dynamic_name);
@ -180,9 +194,11 @@ static bool setup_device(void) {
break;
#endif
#ifdef HAVE_NET_IF_UTUN_H
case DEVICE_TYPE_UTUN:
return setup_utun();
#endif
default:
device_fd = open(device, O_RDWR | O_NONBLOCK);
}
@ -204,70 +220,84 @@ static bool setup_device(void) {
realname = fdevname(device_fd);
#elif defined(HAVE_DEVNAME)
struct stat buf;
if(!fstat(device_fd, &buf))
if(!fstat(device_fd, &buf)) {
realname = devname(buf.st_rdev, S_IFCHR);
}
#endif
if(!realname)
if(!realname) {
realname = device;
}
if(!get_config_string(lookup_config(config_tree, "Interface"), &iface))
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))
} else if(strcmp(iface, strrchr(realname, '/') ? strrchr(realname, '/') + 1 : realname)) {
logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: Interface does not match Device. $INTERFACE might be set incorrectly.");
}
// Configure the device as best as we can
switch(device_type) {
default:
device_type = DEVICE_TYPE_TUN;
case DEVICE_TYPE_TUN:
#ifdef TUNSIFHEAD
{
const int zero = 0;
if(ioctl(device_fd, TUNSIFHEAD, &zero, sizeof zero) == -1) {
if(ioctl(device_fd, TUNSIFHEAD, &zero, sizeof(zero)) == -1) {
logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno));
return false;
}
}
#endif
#if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST)
{
const int mode = IFF_BROADCAST | IFF_MULTICAST;
ioctl(device_fd, TUNSIFMODE, &mode, sizeof mode);
ioctl(device_fd, TUNSIFMODE, &mode, sizeof(mode));
}
#endif
device_info = "Generic BSD tun device";
break;
case DEVICE_TYPE_TUNIFHEAD:
#ifdef TUNSIFHEAD
{
const int one = 1;
if(ioctl(device_fd, TUNSIFHEAD, &one, sizeof one) == -1) {
if(ioctl(device_fd, TUNSIFHEAD, &one, sizeof(one)) == -1) {
logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno));
return false;
}
}
#endif
#if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST)
{
const int mode = IFF_BROADCAST | IFF_MULTICAST;
ioctl(device_fd, TUNSIFMODE, &mode, sizeof mode);
ioctl(device_fd, TUNSIFMODE, &mode, sizeof(mode));
}
#endif
device_info = "Generic BSD tun device";
break;
case DEVICE_TYPE_TAP:
if(routing_mode == RMODE_ROUTER)
if(routing_mode == RMODE_ROUTER) {
overwrite_mac = true;
}
device_info = "Generic BSD tap device";
#ifdef TAPGIFNAME
{
struct ifreq ifr;
if(ioctl(device_fd, TAPGIFNAME, (void *)&ifr) == 0) {
if(iface)
free(iface);
iface = xstrdup(ifr.ifr_name);
}
@ -276,6 +306,7 @@ static bool setup_device(void) {
#endif
break;
#ifdef ENABLE_TUNEMU
case DEVICE_TYPE_TUNEMU:
device_info = "BSD tunemu device";
break;
@ -283,8 +314,11 @@ static bool setup_device(void) {
}
#ifdef SIOCGIFADDR
if(overwrite_mac)
if(overwrite_mac) {
ioctl(device_fd, SIOCGIFADDR, mymac.x);
}
#endif
logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info);
@ -295,17 +329,22 @@ static bool setup_device(void) {
static void close_device(void) {
switch(device_type) {
#ifdef ENABLE_TUNEMU
case DEVICE_TYPE_TUNEMU:
tunemu_close(device_fd);
break;
#endif
default:
close(device_fd);
}
device_fd = -1;
free(device); device = NULL;
free(iface); iface = NULL;
free(device);
device = NULL;
free(iface);
iface = NULL;
device_info = NULL;
}
@ -316,9 +355,9 @@ static bool read_packet(vpn_packet_t *packet) {
case DEVICE_TYPE_TUN:
#ifdef ENABLE_TUNEMU
case DEVICE_TYPE_TUNEMU:
if(device_type == DEVICE_TYPE_TUNEMU)
if(device_type == DEVICE_TYPE_TUNEMU) {
inlen = tunemu_read(device_fd, DATA(packet) + 14, MTU - 14);
else
} else
#endif
inlen = read(device_fd, DATA(packet) + 14, MTU - 14);
@ -333,10 +372,12 @@ static bool read_packet(vpn_packet_t *packet) {
DATA(packet)[12] = 0x08;
DATA(packet)[13] = 0x00;
break;
case 6:
DATA(packet)[12] = 0x86;
DATA(packet)[13] = 0xDD;
break;
default:
logger(DEBUG_TRAFFIC, LOG_ERR,
"Unknown IP version %d while reading packet from %s %s",
@ -410,6 +451,7 @@ static bool write_packet(vpn_packet_t *packet) {
device, strerror(errno));
return false;
}
break;
case DEVICE_TYPE_UTUN:
@ -421,9 +463,11 @@ static bool write_packet(vpn_packet_t *packet) {
case 0x0800:
type = htonl(AF_INET);
break;
case 0x86DD:
type = htonl(AF_INET6);
break;
default:
logger(DEBUG_TRAFFIC, LOG_ERR,
"Unknown address family %x while writing packet to %s %s",
@ -431,13 +475,14 @@ static bool write_packet(vpn_packet_t *packet) {
return false;
}
memcpy(DATA(packet) + 10, &type, sizeof type);
memcpy(DATA(packet) + 10, &type, sizeof(type));
if(write(device_fd, DATA(packet) + 10, packet->len - 10) < 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device,
strerror(errno));
return false;
}
break;
}
@ -447,15 +492,18 @@ static bool write_packet(vpn_packet_t *packet) {
device, strerror(errno));
return false;
}
break;
#ifdef ENABLE_TUNEMU
case DEVICE_TYPE_TUNEMU:
if(tunemu_write(device_fd, DATA(packet) + 14, packet->len - 14) < 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info,
device, strerror(errno));
return false;
}
break;
#endif

View file

@ -49,24 +49,21 @@
#define PPPIOCCONNECT _IOW('t', 58, int)
#define PPPIOCGUNIT _IOR('t', 86, int)
struct sockaddr_ppp
{
struct sockaddr_ppp {
u_int8_t ppp_len;
u_int8_t ppp_family;
u_int16_t ppp_proto;
u_int32_t ppp_cookie;
};
enum NPmode
{
enum NPmode {
NPMODE_PASS,
NPMODE_DROP,
NPMODE_ERROR,
NPMODE_QUEUE
};
struct npioctl
{
struct npioctl {
int protocol;
enum NPmode mode;
};
@ -83,58 +80,55 @@ static pcap_t *pcap = NULL;
static int data_buffer_length = 0;
static char *data_buffer = NULL;
static void tun_error(char *format, ...)
{
static void tun_error(char *format, ...) {
va_list vl;
va_start(vl, format);
vsnprintf(tunemu_error, sizeof tunemu_error, format, vl);
vsnprintf(tunemu_error, sizeof(tunemu_error), format, vl);
va_end(vl);
}
static void tun_noerror()
{
static void tun_noerror() {
*tunemu_error = 0;
}
static void closeall()
{
static void closeall() {
int fd = getdtablesize();
while (fd--)
while(fd--) {
close(fd);
}
open("/dev/null", O_RDWR, 0);
dup(0);
dup(0);
}
static int ppp_load_kext()
{
static int ppp_load_kext() {
int pid = fork();
if (pid < 0)
{
if(pid < 0) {
tun_error("fork for ppp kext: %s", strerror(errno));
return -1;
}
if (pid == 0)
{
if(pid == 0) {
closeall();
execle("/sbin/kextload", "kextload", PPP_KEXT_PATH, NULL, NULL);
exit(1);
}
int status;
while (waitpid(pid, &status, 0) < 0)
{
if (errno == EINTR)
while(waitpid(pid, &status, 0) < 0) {
if(errno == EINTR) {
continue;
}
tun_error("waitpid for ppp kext: %s", strerror(errno));
return -1;
}
if (WEXITSTATUS(status) != 0)
{
if(WEXITSTATUS(status) != 0) {
tun_error("could not load ppp kext \"%s\"", PPP_KEXT_PATH);
return -1;
}
@ -143,18 +137,18 @@ static int ppp_load_kext()
return 0;
}
static int ppp_new_instance()
{
static int ppp_new_instance() {
// create ppp socket
int ppp_sockfd = socket(PF_PPP, SOCK_RAW, PPPPROTO_CTL);
if (ppp_sockfd < 0)
{
if (ppp_load_kext() < 0)
if(ppp_sockfd < 0) {
if(ppp_load_kext() < 0) {
return -1;
}
ppp_sockfd = socket(PF_PPP, SOCK_RAW, PPPPROTO_CTL);
if (ppp_sockfd < 0)
{
if(ppp_sockfd < 0) {
tun_error("creating ppp socket: %s", strerror(errno));
return -1;
}
@ -166,8 +160,8 @@ static int ppp_new_instance()
pppaddr.ppp_family = AF_PPP;
pppaddr.ppp_proto = PPPPROTO_CTL;
pppaddr.ppp_cookie = 0;
if (connect(ppp_sockfd, (struct sockaddr *)&pppaddr, sizeof(struct sockaddr_ppp)) < 0)
{
if(connect(ppp_sockfd, (struct sockaddr *)&pppaddr, sizeof(struct sockaddr_ppp)) < 0) {
tun_error("connecting ppp socket: %s", strerror(errno));
close(ppp_sockfd);
return -1;
@ -177,15 +171,15 @@ static int ppp_new_instance()
return ppp_sockfd;
}
static int ppp_new_unit(int *unit_number)
{
static int ppp_new_unit(int *unit_number) {
int fd = ppp_new_instance();
if (fd < 0)
if(fd < 0) {
return -1;
}
// create ppp unit
if (ioctl(fd, PPPIOCNEWUNIT, unit_number) < 0)
{
if(ioctl(fd, PPPIOCNEWUNIT, unit_number) < 0) {
tun_error("creating ppp unit: %s", strerror(errno));
close(fd);
return -1;
@ -195,12 +189,11 @@ static int ppp_new_unit(int *unit_number)
return fd;
}
static int ppp_setup_unit(int unit_fd)
{
static int ppp_setup_unit(int unit_fd) {
// send traffic to program
int flags = SC_LOOP_TRAFFIC;
if (ioctl(unit_fd, PPPIOCSFLAGS, &flags) < 0)
{
if(ioctl(unit_fd, PPPIOCSFLAGS, &flags) < 0) {
tun_error("setting ppp loopback mode: %s", strerror(errno));
return -1;
}
@ -209,8 +202,8 @@ static int ppp_setup_unit(int unit_fd)
struct npioctl npi;
npi.protocol = PPP_IP;
npi.mode = NPMODE_PASS;
if (ioctl(unit_fd, PPPIOCSNPMODE, &npi) < 0)
{
if(ioctl(unit_fd, PPPIOCSNPMODE, &npi) < 0) {
tun_error("starting ppp unit: %s", strerror(errno));
return -1;
}
@ -219,10 +212,8 @@ static int ppp_setup_unit(int unit_fd)
return 0;
}
static int open_pcap()
{
if (pcap != NULL)
{
static int open_pcap() {
if(pcap != NULL) {
pcap_use_count++;
return 0;
}
@ -231,8 +222,7 @@ static int open_pcap()
pcap = pcap_open_live("lo0", BUFSIZ, 0, 1, errbuf);
pcap_use_count = 1;
if (pcap == NULL)
{
if(pcap == NULL) {
tun_error("opening pcap: %s", errbuf);
return -1;
}
@ -241,59 +231,57 @@ static int open_pcap()
return 0;
}
static void close_pcap()
{
if (pcap == NULL)
static void close_pcap() {
if(pcap == NULL) {
return;
}
pcap_use_count--;
if (pcap_use_count == 0)
{
if(pcap_use_count == 0) {
pcap_close(pcap);
pcap = NULL;
}
}
static void allocate_data_buffer(int size)
{
if (data_buffer_length < size)
{
static void allocate_data_buffer(int size) {
if(data_buffer_length < size) {
free(data_buffer);
data_buffer_length = size;
data_buffer = malloc(data_buffer_length);
}
}
static void make_device_name(tunemu_device device, int unit_number)
{
static void make_device_name(tunemu_device device, int unit_number) {
snprintf(device, sizeof(tunemu_device), "ppp%d", unit_number);
}
static int check_device_name(tunemu_device device)
{
if (strlen(device) < 4)
static int check_device_name(tunemu_device device) {
if(strlen(device) < 4) {
return -1;
}
int unit_number = atoi(device + 3);
if (unit_number < 0 || unit_number > 999)
if(unit_number < 0 || unit_number > 999) {
return -1;
}
tunemu_device compare;
make_device_name(compare, unit_number);
if (strcmp(device, compare) != 0)
if(strcmp(device, compare) != 0) {
return -1;
}
return 0;
}
int tunemu_open(tunemu_device device)
{
int tunemu_open(tunemu_device device) {
int ppp_unit_number = -1;
if (device[0] != 0)
{
if (check_device_name(device) < 0)
{
if(device[0] != 0) {
if(check_device_name(device) < 0) {
tun_error("invalid device name \"%s\"", device);
return -1;
}
@ -302,17 +290,17 @@ int tunemu_open(tunemu_device device)
}
int ppp_unit_fd = ppp_new_unit(&ppp_unit_number);
if (ppp_unit_fd < 0)
return -1;
if (ppp_setup_unit(ppp_unit_fd) < 0)
{
if(ppp_unit_fd < 0) {
return -1;
}
if(ppp_setup_unit(ppp_unit_fd) < 0) {
close(ppp_unit_fd);
return -1;
}
if (open_pcap() < 0)
{
if(open_pcap() < 0) {
close(ppp_unit_fd);
return -1;
}
@ -322,39 +310,40 @@ int tunemu_open(tunemu_device device)
return ppp_unit_fd;
}
int tunemu_close(int ppp_sockfd)
{
int tunemu_close(int ppp_sockfd) {
int ret = close(ppp_sockfd);
if (ret == 0)
if(ret == 0) {
close_pcap();
}
return ret;
}
int tunemu_read(int ppp_sockfd, char *buffer, int length)
{
int tunemu_read(int ppp_sockfd, char *buffer, int length) {
allocate_data_buffer(length + 2);
length = read(ppp_sockfd, data_buffer, length + 2);
if (length < 0)
{
if(length < 0) {
tun_error("reading packet: %s", strerror(errno));
return length;
}
tun_noerror();
length -= 2;
if (length < 0)
if(length < 0) {
return 0;
}
memcpy(buffer, data_buffer + 2, length);
return length;
}
int tunemu_write(int ppp_sockfd, char *buffer, int length)
{
int tunemu_write(int ppp_sockfd, char *buffer, int length) {
allocate_data_buffer(length + 4);
data_buffer[0] = 0x02;
@ -364,23 +353,25 @@ int tunemu_write(int ppp_sockfd, char *buffer, int length)
memcpy(data_buffer + 4, buffer, length);
if (pcap == NULL)
{
if(pcap == NULL) {
tun_error("pcap not open");
return -1;
}
length = pcap_inject(pcap, data_buffer, length + 4);
if (length < 0)
{
if(length < 0) {
tun_error("injecting packet: %s", pcap_geterr(pcap));
return length;
}
tun_noerror();
length -= 4;
if (length < 0)
if(length < 0) {
return 0;
}
return length;
}

View file

@ -22,7 +22,7 @@
#include "buffer.h"
#include "xalloc.h"
void buffer_compact(buffer_t *buffer, int maxsize) {
void buffer_compact(buffer_t *buffer, uint32_t maxsize) {
if(buffer->len >= maxsize || buffer->offset / 7 > buffer->len / 8) {
memmove(buffer->data, buffer->data + buffer->offset, buffer->len - buffer->offset);
buffer->len -= buffer->offset;
@ -32,7 +32,7 @@ void buffer_compact(buffer_t *buffer, int maxsize) {
// Make sure we can add size bytes to the buffer, and return a pointer to the start of those bytes.
char *buffer_prepare(buffer_t *buffer, int size) {
char *buffer_prepare(buffer_t *buffer, uint32_t size) {
if(!buffer->data) {
buffer->maxlen = size;
buffer->data = xmalloc(size);
@ -58,13 +58,13 @@ char *buffer_prepare(buffer_t *buffer, int size) {
// Copy data into the buffer.
void buffer_add(buffer_t *buffer, const char *data, int size) {
void buffer_add(buffer_t *buffer, const char *data, uint32_t size) {
memcpy(buffer_prepare(buffer, size), data, size);
}
// Remove given number of bytes from the buffer, return a pointer to the start of them.
static char *buffer_consume(buffer_t *buffer, int size) {
static char *buffer_consume(buffer_t *buffer, uint32_t size) {
char *start = buffer->data + buffer->offset;
buffer->offset += size;
@ -82,19 +82,21 @@ static char *buffer_consume(buffer_t *buffer, int size) {
char *buffer_readline(buffer_t *buffer) {
char *newline = memchr(buffer->data + buffer->offset, '\n', buffer->len - buffer->offset);
if(!newline)
if(!newline) {
return NULL;
}
int len = newline + 1 - (buffer->data + buffer->offset);
uint32_t len = newline + 1 - (buffer->data + buffer->offset);
*newline = 0;
return buffer_consume(buffer, len);
}
// Check if we have enough bytes in the buffer, and if so, return a pointer to the start of them.
char *buffer_read(buffer_t *buffer, int size) {
if(buffer->len - buffer->offset < size)
char *buffer_read(buffer_t *buffer, uint32_t size) {
if(buffer->len - buffer->offset < size) {
return NULL;
}
return buffer_consume(buffer, size);
}

View file

@ -1,18 +1,18 @@
#ifndef __TINC_BUFFER_H__
#define __TINC_BUFFER_H__
#ifndef TINC_BUFFER_H
#define TINC_BUFFER_H
typedef struct buffer_t {
char *data;
int maxlen;
int len;
int offset;
uint32_t maxlen;
uint32_t len;
uint32_t offset;
} buffer_t;
extern void buffer_compact(buffer_t *buffer, int maxsize);
extern char *buffer_prepare(buffer_t *buffer, int size);
extern void buffer_add(buffer_t *buffer, const char *data, int size);
extern void buffer_compact(buffer_t *buffer, uint32_t maxsize);
extern char *buffer_prepare(buffer_t *buffer, uint32_t size);
extern void buffer_add(buffer_t *buffer, const char *data, uint32_t size);
extern char *buffer_readline(buffer_t *buffer);
extern char *buffer_read(buffer_t *buffer, int size);
extern char *buffer_read(buffer_t *buffer, uint32_t size);
extern void buffer_clear(buffer_t *buffer);
#endif

View file

@ -11,26 +11,23 @@ struct chacha_poly1305_ctx {
struct chacha_ctx main_ctx, header_ctx;
};
chacha_poly1305_ctx_t *chacha_poly1305_init(void)
{
chacha_poly1305_ctx_t *ctx = xzalloc(sizeof *ctx);
chacha_poly1305_ctx_t *chacha_poly1305_init(void) {
chacha_poly1305_ctx_t *ctx = xzalloc(sizeof(*ctx));
return ctx;
}
void chacha_poly1305_exit(chacha_poly1305_ctx_t *ctx)
{
void chacha_poly1305_exit(chacha_poly1305_ctx_t *ctx) {
free(ctx);
}
bool chacha_poly1305_set_key(chacha_poly1305_ctx_t *ctx, const void *key)
{
bool chacha_poly1305_set_key(chacha_poly1305_ctx_t *ctx, const void *vkey) {
const uint8_t *key = vkey;
chacha_keysetup(&ctx->main_ctx, key, 256);
chacha_keysetup(&ctx->header_ctx, key + 32, 256);
return true;
}
static void put_u64(void *vp, uint64_t v)
{
static void put_u64(void *vp, uint64_t v) {
uint8_t *p = (uint8_t *) vp;
p[0] = (uint8_t)(v >> 56) & 0xff;
@ -43,10 +40,11 @@ static void put_u64(void *vp, uint64_t v)
p[7] = (uint8_t) v & 0xff;
}
bool chacha_poly1305_encrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const void *indata, size_t inlen, void *outdata, size_t *outlen) {
bool chacha_poly1305_encrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const void *indata, size_t inlen, void *voutdata, size_t *outlen) {
uint8_t seqbuf[8];
const uint8_t one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB little-endian */
uint8_t poly_key[POLY1305_KEYLEN];
uint8_t *outdata = voutdata;
/*
* Run ChaCha20 once to generate the Poly1305 key. The IV is the
@ -63,16 +61,18 @@ bool chacha_poly1305_encrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const v
chacha_encrypt_bytes(&ctx->main_ctx, indata, outdata, inlen);
poly1305_auth(outdata + inlen, outdata, inlen, poly_key);
if (outlen)
if(outlen) {
*outlen = inlen + POLY1305_TAGLEN;
}
return true;
}
bool chacha_poly1305_decrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const void *indata, size_t inlen, void *outdata, size_t *outlen) {
bool chacha_poly1305_decrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const void *vindata, size_t inlen, void *outdata, size_t *outlen) {
uint8_t seqbuf[8];
const uint8_t one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB little-endian */
uint8_t expected_tag[POLY1305_TAGLEN], poly_key[POLY1305_KEYLEN];
const uint8_t *indata = vindata;
/*
* Run ChaCha20 once to generate the Poly1305 key. The IV is the
@ -91,13 +91,16 @@ bool chacha_poly1305_decrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const v
const uint8_t *tag = indata + inlen;
poly1305_auth(expected_tag, indata, inlen, poly_key);
if (memcmp(expected_tag, tag, POLY1305_TAGLEN))
if(memcmp(expected_tag, tag, POLY1305_TAGLEN)) {
return false;
}
chacha_encrypt_bytes(&ctx->main_ctx, indata, outdata, inlen);
if (outlen)
if(outlen) {
*outlen = inlen;
}
return true;
}

View file

@ -47,20 +47,21 @@ typedef struct chacha_ctx chacha_ctx;
static const char sigma[16] = "expand 32-byte k";
static const char tau[16] = "expand 16-byte k";
void chacha_keysetup(chacha_ctx *x, const uint8_t *k, uint32_t kbits)
{
void chacha_keysetup(chacha_ctx *x, const uint8_t *k, uint32_t kbits) {
const char *constants;
x->input[4] = U8TO32_LITTLE(k + 0);
x->input[5] = U8TO32_LITTLE(k + 4);
x->input[6] = U8TO32_LITTLE(k + 8);
x->input[7] = U8TO32_LITTLE(k + 12);
if(kbits == 256) { /* recommended */
k += 16;
constants = sigma;
} else { /* kbits == 128 */
constants = tau;
}
x->input[8] = U8TO32_LITTLE(k + 0);
x->input[9] = U8TO32_LITTLE(k + 4);
x->input[10] = U8TO32_LITTLE(k + 8);
@ -71,8 +72,7 @@ void chacha_keysetup(chacha_ctx *x, const uint8_t *k, uint32_t kbits)
x->input[3] = U8TO32_LITTLE(constants + 12);
}
void chacha_ivsetup(chacha_ctx *x, const uint8_t *iv, const uint8_t *counter)
{
void chacha_ivsetup(chacha_ctx *x, const uint8_t *iv, const uint8_t *counter) {
x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0);
x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4);
x->input[14] = U8TO32_LITTLE(iv + 0);
@ -80,16 +80,16 @@ void chacha_ivsetup(chacha_ctx *x, const uint8_t *iv, const uint8_t *counter)
}
void
chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes)
{
chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes) {
uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
uint8_t *ctarget = NULL;
uint8_t tmp[64];
uint32_t i;
if (!bytes)
if(!bytes) {
return;
}
j0 = x->input[0];
j1 = x->input[1];
@ -110,12 +110,15 @@ chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes
for(;;) {
if(bytes < 64) {
for (i = 0; i < bytes; ++i)
for(i = 0; i < bytes; ++i) {
tmp[i] = m[i];
}
m = tmp;
ctarget = c;
c = tmp;
}
x0 = j0;
x1 = j1;
x2 = j2;
@ -132,6 +135,7 @@ chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes
x13 = j13;
x14 = j14;
x15 = j15;
for(i = 20; i > 0; i -= 2) {
QUARTERROUND(x0, x4, x8, x12)
QUARTERROUND(x1, x5, x9, x13)
@ -142,6 +146,7 @@ chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes
QUARTERROUND(x2, x7, x8, x13)
QUARTERROUND(x3, x4, x9, x14)
}
x0 = PLUS(x0, j0);
x1 = PLUS(x1, j1);
x2 = PLUS(x2, j2);
@ -177,6 +182,7 @@ chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes
x15 = XOR(x15, U8TO32_LITTLE(m + 60));
j12 = PLUSONE(j12);
if(!j12) {
j13 = PLUSONE(j13);
/* stopping at 2^70 bytes per nonce is user's responsibility */
@ -201,13 +207,16 @@ chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes
if(bytes <= 64) {
if(bytes < 64) {
for (i = 0; i < bytes; ++i)
for(i = 0; i < bytes; ++i) {
ctarget[i] = c[i];
}
}
x->input[12] = j12;
x->input[13] = j13;
return;
}
bytes -= 64;
c += 64;
m += 64;

View file

@ -24,8 +24,7 @@
} while (0)
void
poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t inlen, const unsigned char key[POLY1305_KEYLEN])
{
poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t inlen, const unsigned char key[POLY1305_KEYLEN]) {
uint32_t t0, t1, t2, t3;
uint32_t h0, h1, h2, h3, h4;
uint32_t r0, r1, r2, r3, r4;
@ -71,8 +70,9 @@ poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t
h4 = 0;
/* full blocks */
if (inlen < 16)
if(inlen < 16) {
goto poly1305_donna_atmost15bytes;
}
poly1305_donna_16bytes:
m += 16;
@ -112,19 +112,27 @@ poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t
b = (uint32_t)(t[4] >> 26);
h0 += b * 5;
if (inlen >= 16)
if(inlen >= 16) {
goto poly1305_donna_16bytes;
}
/* final bytes */
poly1305_donna_atmost15bytes:
if (!inlen)
goto poly1305_donna_finish;
for (j = 0; j < inlen; j++)
if(!inlen) {
goto poly1305_donna_finish;
}
for(j = 0; j < inlen; j++) {
mp[j] = m[j];
}
mp[j++] = 1;
for (; j < 16; j++)
for(; j < 16; j++) {
mp[j] = 0;
}
inlen = 0;
t0 = U8TO32_LE(mp + 0);

View file

@ -1,3 +1,6 @@
#ifndef TINC_CIPHER_H
#define TINC_CIPHER_H
/*
cipher.h -- header file cipher.c
Copyright (C) 2007-2016 Guus Sliepen <guus@tinc-vpn.org>
@ -17,9 +20,6 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __TINC_CIPHER_H__
#define __TINC_CIPHER_H__
#define CIPHER_MAX_BLOCK_SIZE 32
#define CIPHER_MAX_IV_SIZE 16
#define CIPHER_MAX_KEY_SIZE 32
@ -28,19 +28,18 @@
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 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__));
extern bool cipher_encrypt(cipher_t *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) __attribute__ ((__warn_unused_result__));
extern bool cipher_decrypt(cipher_t *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) __attribute__ ((__warn_unused_result__));
extern int cipher_get_nid(const cipher_t *);
extern bool cipher_active(const cipher_t *);
extern cipher_t *cipher_open_by_name(const char *name) __attribute__((__malloc__));
extern cipher_t *cipher_open_by_nid(int nid) __attribute__((__malloc__));
extern void cipher_close(cipher_t *cipher);
extern size_t cipher_keylength(const cipher_t *cipher);
extern size_t cipher_blocksize(const cipher_t *cipher);
extern uint64_t cipher_budget(const cipher_t *cipher);
extern bool cipher_set_key(cipher_t *cipher, void *key, bool encrypt) __attribute__((__warn_unused_result__));
extern bool cipher_set_key_from_rsa(cipher_t *cipher, void *rsa, size_t len, bool encrypt) __attribute__((__warn_unused_result__));
extern bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) __attribute__((__warn_unused_result__));
extern bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) __attribute__((__warn_unused_result__));
extern int cipher_get_nid(const cipher_t *cipher);
extern bool cipher_active(const cipher_t *cipher);
#endif

View file

@ -46,21 +46,25 @@ static int config_compare(const config_t *a, const config_t *b) {
result = strcasecmp(a->variable, b->variable);
if(result)
if(result) {
return result;
}
/* give priority to command line options */
result = !b->file - !a->file;
if (result)
if(result) {
return result;
}
result = a->line - b->line;
if(result)
if(result) {
return result;
else
} else {
return a->file ? strcmp(a->file, b->file) : 0;
}
}
void init_configuration(splay_tree_t **config_tree) {
*config_tree = splay_alloc_tree((splay_compare_t) config_compare, (splay_action_t) free_config);
@ -76,15 +80,9 @@ config_t *new_config(void) {
}
void free_config(config_t *cfg) {
if(cfg->variable)
free(cfg->variable);
if(cfg->value)
free(cfg->value);
if(cfg->file)
free(cfg->file);
free(cfg);
}
@ -101,11 +99,13 @@ config_t *lookup_config(splay_tree_t *config_tree, char *variable) {
found = splay_search_closest_greater(config_tree, &cfg);
if(!found)
if(!found) {
return NULL;
}
if(strcasecmp(found->variable, variable))
if(strcasecmp(found->variable, variable)) {
return NULL;
}
return found;
}
@ -120,17 +120,19 @@ config_t *lookup_config_next(splay_tree_t *config_tree, const config_t *cfg) {
if(node->next) {
found = node->next->data;
if(!strcasecmp(found->variable, cfg->variable))
if(!strcasecmp(found->variable, cfg->variable)) {
return found;
}
}
}
return NULL;
}
bool get_config_bool(const config_t *cfg, bool *result) {
if(!cfg)
if(!cfg) {
return false;
}
if(!strcasecmp(cfg->value, "yes")) {
*result = true;
@ -147,11 +149,13 @@ bool get_config_bool(const config_t *cfg, bool *result) {
}
bool get_config_int(const config_t *cfg, int *result) {
if(!cfg)
if(!cfg) {
return false;
}
if(sscanf(cfg->value, "%d", result) == 1)
if(sscanf(cfg->value, "%d", result) == 1) {
return true;
}
logger(DEBUG_ALWAYS, LOG_ERR, "Integer expected for configuration variable %s in %s line %d",
cfg->variable, cfg->file, cfg->line);
@ -160,8 +164,9 @@ bool get_config_int(const config_t *cfg, int *result) {
}
bool get_config_string(const config_t *cfg, char **result) {
if(!cfg)
if(!cfg) {
return false;
}
*result = xstrdup(cfg->value);
@ -171,8 +176,9 @@ bool get_config_string(const config_t *cfg, char **result) {
bool get_config_address(const config_t *cfg, struct addrinfo **result) {
struct addrinfo *ai;
if(!cfg)
if(!cfg) {
return false;
}
ai = str2addrinfo(cfg->value, NULL, 0);
@ -188,10 +194,11 @@ bool get_config_address(const config_t *cfg, struct addrinfo **result) {
}
bool get_config_subnet(const config_t *cfg, subnet_t **result) {
subnet_t subnet = {NULL};
subnet_t subnet = {0};
if(!cfg)
if(!cfg) {
return false;
}
if(!str2net(&subnet, cfg->value)) {
logger(DEBUG_ALWAYS, LOG_ERR, "Subnet expected for configuration variable %s in %s line %d",
@ -202,9 +209,9 @@ bool get_config_subnet(const config_t *cfg, subnet_t ** result) {
/* Teach newbies what subnets are... */
if(((subnet.type == SUBNET_IPV4)
&& !maskcheck(&subnet.net.ipv4.address, subnet.net.ipv4.prefixlength, sizeof subnet.net.ipv4.address))
&& !maskcheck(&subnet.net.ipv4.address, subnet.net.ipv4.prefixlength, sizeof(subnet.net.ipv4.address)))
|| ((subnet.type == SUBNET_IPV6)
&& !maskcheck(&subnet.net.ipv6.address, subnet.net.ipv6.prefixlength, sizeof subnet.net.ipv6.address))) {
&& !maskcheck(&subnet.net.ipv6.address, subnet.net.ipv6.prefixlength, sizeof(subnet.net.ipv6.address)))) {
logger(DEBUG_ALWAYS, LOG_ERR, "Network address and prefix length do not match for configuration variable %s in %s line %d",
cfg->variable, cfg->file, cfg->line);
return false;
@ -222,23 +229,28 @@ static char *readline(FILE * fp, char *buf, size_t buflen) {
char *newline = NULL;
char *p;
if(feof(fp))
if(feof(fp)) {
return NULL;
}
p = fgets(buf, buflen, fp);
if(!p)
if(!p) {
return NULL;
}
newline = strchr(p, '\n');
if(!newline)
if(!newline) {
return buf;
}
/* kill newline and carriage return if necessary */
*newline = '\0';
if(newline > p && newline[-1] == '\r')
if(newline > p && newline[-1] == '\r') {
newline[-1] = '\0';
}
return buf;
}
@ -250,26 +262,32 @@ config_t *parse_config_line(char *line, const char *fname, int lineno) {
variable = value = line;
eol = line + strlen(line);
while(strchr("\t ", *--eol))
while(strchr("\t ", *--eol)) {
*eol = '\0';
}
len = strcspn(value, "\t =");
value += len;
value += strspn(value, "\t ");
if(*value == '=') {
value++;
value += strspn(value, "\t ");
}
variable[len] = '\0';
if(!*value) {
const char err[] = "No value for variable";
if(fname)
logger(DEBUG_ALWAYS, LOG_ERR, "%s `%s' on line %d while reading config file %s",
err, variable, lineno, fname);
else
logger(DEBUG_ALWAYS, LOG_ERR, "%s `%s' in command line option %d",
err, variable, lineno);
return NULL;
}
@ -286,7 +304,7 @@ config_t *parse_config_line(char *line, const char *fname, int lineno) {
Parse a configuration file and put the results in the configuration tree
starting at *base.
*/
bool read_config_file(splay_tree_t *config_tree, const char *fname) {
bool read_config_file(splay_tree_t *config_tree, const char *fname, bool verbose) {
FILE *fp;
char buffer[MAX_STRING_SIZE];
char *line;
@ -298,27 +316,32 @@ bool read_config_file(splay_tree_t *config_tree, const char *fname) {
fp = fopen(fname, "r");
if(!fp) {
logger(DEBUG_ALWAYS, LOG_DEBUG, "Cannot open config file %s: %s", fname, strerror(errno));
logger(verbose ? DEBUG_ALWAYS : DEBUG_CONNECTIONS, LOG_ERR, "Cannot open config file %s: %s", fname, strerror(errno));
return false;
}
for(;;) {
line = readline(fp, buffer, sizeof buffer);
line = readline(fp, buffer, sizeof(buffer));
if(!line) {
if(feof(fp))
if(feof(fp)) {
result = true;
}
break;
}
lineno++;
if(!*line || *line == '#')
if(!*line || *line == '#') {
continue;
}
if(ignore) {
if(!strncmp(line, "-----END", 8))
if(!strncmp(line, "-----END", 8)) {
ignore = false;
}
continue;
}
@ -328,8 +351,11 @@ bool read_config_file(splay_tree_t *config_tree, const char *fname) {
}
cfg = parse_config_line(line, fname, lineno);
if (!cfg)
if(!cfg) {
break;
}
config_add(config_tree, cfg);
}
@ -346,19 +372,24 @@ void read_config_options(splay_tree_t *config_tree, const char *prefix) {
config_t *new;
if(!prefix) {
if(strchr(cfg->variable, '.'))
if(strchr(cfg->variable, '.')) {
continue;
}
} else {
if(strncmp(prefix, cfg->variable, prefix_len) ||
cfg->variable[prefix_len] != '.')
cfg->variable[prefix_len] != '.') {
continue;
}
}
new = new_config();
if(prefix)
if(prefix) {
new->variable = xstrdup(cfg->variable + prefix_len + 1);
else
} else {
new->variable = xstrdup(cfg->variable);
}
new->value = xstrdup(cfg->value);
new->file = NULL;
new->line = cfg->line;
@ -373,52 +404,57 @@ bool read_server_config(void) {
read_config_options(config_tree, NULL);
snprintf(fname, sizeof fname, "%s" SLASH "tinc.conf", confbase);
snprintf(fname, sizeof(fname), "%s" SLASH "tinc.conf", confbase);
errno = 0;
x = read_config_file(config_tree, fname);
x = read_config_file(config_tree, fname, true);
// We will try to read the conf files in the "conf.d" dir
if(x) {
char dname[PATH_MAX];
snprintf(dname, sizeof dname, "%s" SLASH "conf.d", confbase);
snprintf(dname, sizeof(dname), "%s" SLASH "conf.d", confbase);
DIR *dir = opendir(dname);
// If we can find this dir
if(dir) {
struct dirent *ep;
// We list all the files in it
while(x && (ep = readdir(dir))) {
size_t l = strlen(ep->d_name);
// And we try to read the ones that end with ".conf"
if(l > 5 && !strcmp(".conf", & ep->d_name[ l - 5 ])) {
snprintf(fname, sizeof fname, "%s" SLASH "%s", dname, ep->d_name);
x = read_config_file(config_tree, fname);
if((size_t)snprintf(fname, sizeof(fname), "%s" SLASH "%s", dname, ep->d_name) >= sizeof(fname)) {
logger(DEBUG_ALWAYS, LOG_ERR, "Pathname too long: %s/%s", dname, ep->d_name);
return false;
}
x = read_config_file(config_tree, fname, true);
}
}
closedir(dir);
}
}
if(!x && errno)
if(!x && errno) {
logger(DEBUG_ALWAYS, LOG_ERR, "Failed to read `%s': %s", fname, strerror(errno));
}
return x;
}
bool read_host_config(splay_tree_t *config_tree, const char *name) {
char fname[PATH_MAX];
bool x;
bool read_host_config(splay_tree_t *config_tree, const char *name, bool verbose) {
read_config_options(config_tree, name);
snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, name);
x = read_config_file(config_tree, fname);
return x;
char fname[PATH_MAX];
snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, name);
return read_config_file(config_tree, fname, verbose);
}
bool append_config_file(const char *name, const char *key, const char *value) {
char fname[PATH_MAX];
snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, name);
snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, name);
FILE *fp = fopen(fname, "a");

View file

@ -1,3 +1,6 @@
#ifndef TINC_CONF_H
#define TINC_CONF_H
/*
conf.h -- header for conf.c
Copyright (C) 1998-2005 Ivo Timmermans
@ -18,9 +21,6 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __TINC_CONF_H__
#define __TINC_CONF_H__
#include "list.h"
#include "splay_tree.h"
#include "subnet.h"
@ -41,24 +41,24 @@ extern int maxtimeout;
extern bool bypass_security;
extern list_t *cmdline_conf;
extern void init_configuration(splay_tree_t **);
extern void exit_configuration(splay_tree_t **);
extern void init_configuration(splay_tree_t **config_tree);
extern void exit_configuration(splay_tree_t **config_tree);
extern config_t *new_config(void) __attribute__((__malloc__));
extern void free_config(config_t *);
extern void config_add(splay_tree_t *, config_t *);
extern config_t *lookup_config(splay_tree_t *, char *);
extern config_t *lookup_config_next(splay_tree_t *, const config_t *);
extern bool get_config_bool(const config_t *, bool *);
extern bool get_config_int(const config_t *, int *);
extern bool get_config_string(const config_t *, char **);
extern bool get_config_address(const config_t *, struct addrinfo **);
extern bool get_config_subnet(const config_t *, struct subnet_t **);
extern void free_config(config_t *config);
extern void config_add(splay_tree_t *config_tree, config_t *config);
extern config_t *lookup_config(splay_tree_t *config_tree, char *variable);
extern config_t *lookup_config_next(splay_tree_t *config_tree, const config_t *config);
extern bool get_config_bool(const config_t *config, bool *result);
extern bool get_config_int(const config_t *config, int *result);
extern bool get_config_string(const config_t *config, char **result);
extern bool get_config_address(const config_t *config, struct addrinfo **result);
extern bool get_config_subnet(const config_t *config, struct subnet_t **result);
extern config_t *parse_config_line(char *, const char *, int);
extern bool read_config_file(splay_tree_t *, const char *);
extern void read_config_options(splay_tree_t *, const char *);
extern config_t *parse_config_line(char *line, const char *fname, int lineno);
extern bool read_config_file(splay_tree_t *config_tree, const char *filename, bool verbose);
extern void read_config_options(splay_tree_t *config_tree, const char *prefix);
extern bool read_server_config(void);
extern bool read_host_config(splay_tree_t *, const char *);
extern bool append_config_file(const char *, const char *, const char *);
extern bool read_host_config(splay_tree_t *config_tree, const char *name, bool verbose);
extern bool append_config_file(const char *name, const char *key, const char *value);
#endif /* __TINC_CONF_H__ */
#endif

View file

@ -27,6 +27,7 @@
#include "control_common.h"
#include "list.h"
#include "logger.h"
#include "net.h"
#include "rsa.h"
#include "subnet.h"
#include "utils.h"
@ -52,8 +53,9 @@ connection_t *new_connection(void) {
}
void free_connection(connection_t *c) {
if(!c)
if(!c) {
return;
}
#ifndef DISABLE_LEGACY
cipher_close(c->incipher);
@ -67,20 +69,27 @@ void free_connection(connection_t *c) {
ecdsa_free(c->ecdsa);
free(c->hischallenge);
free(c->mychallenge);
buffer_clear(&c->inbuf);
buffer_clear(&c->outbuf);
io_del(&c->io);
if(c->socket > 0)
if(c->socket > 0) {
if(c->status.tarpit) {
tarpit(c->socket);
} else {
closesocket(c->socket);
}
}
free(c->name);
free(c->hostname);
if(c->config_tree)
if(c->config_tree) {
exit_configuration(&c->config_tree);
}
free(c);
}
@ -98,7 +107,7 @@ bool dump_connections(connection_t *cdump) {
send_request(cdump, "%d %d %s %s %x %d %x",
CONTROL, REQ_DUMP_CONNECTIONS,
c->name, c->hostname, c->options, c->socket,
bitfield_to_int(&c->status, sizeof c->status));
bitfield_to_int(&c->status, sizeof(c->status)));
}
return send_request(cdump, "%d %d", CONTROL, REQ_DUMP_CONNECTIONS);

View file

@ -1,3 +1,6 @@
#ifndef TINC_CONNECTION_H
#define TINC_CONNECTION_H
/*
connection.h -- header for connection.c
Copyright (C) 2000-2013 Guus Sliepen <guus@tinc-vpn.org>,
@ -18,9 +21,6 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __TINC_CONNECTION_H__
#define __TINC_CONNECTION_H__
#include "buffer.h"
#include "cipher.h"
#include "digest.h"
@ -49,7 +49,8 @@ typedef struct connection_status_t {
unsigned int log: 1; /* 1 if this is a control connection requesting log dump */
unsigned int invitation: 1; /* 1 if this is an invitation */
unsigned int invitation_used: 1; /* 1 if the invitation has been consumed */
unsigned int unused:18;
unsigned int tarpit: 1; /* 1 if the connection should be added to the tarpit */
unsigned int unused: 17;
} connection_status_t;
#include "ecdsa.h"
@ -94,6 +95,7 @@ typedef struct connection_t {
int outcompression;
char *hischallenge; /* The challenge we sent to him */
char *mychallenge; /* The challenge we received */
struct buffer_t inbuf;
struct buffer_t outbuf;
@ -113,9 +115,9 @@ extern connection_t *everyone;
extern void init_connections(void);
extern void exit_connections(void);
extern connection_t *new_connection(void) __attribute__((__malloc__));
extern void free_connection(connection_t *);
extern void connection_add(connection_t *);
extern void connection_del(connection_t *);
extern bool dump_connections(struct connection_t *);
extern void free_connection(connection_t *c);
extern void connection_add(connection_t *c);
extern void connection_del(connection_t *c);
extern bool dump_connections(struct connection_t *c);
#endif /* __TINC_CONNECTION_H__ */
#endif

View file

@ -79,11 +79,17 @@ bool control_h(connection_t *c, const char *request) {
case REQ_SET_DEBUG: {
int new_level;
if(sscanf(request, "%*d %*d %d", &new_level) != 1)
if(sscanf(request, "%*d %*d %d", &new_level) != 1) {
return false;
}
send_request(c, "%d %d %d", CONTROL, REQ_SET_DEBUG, debug_level);
if(new_level >= 0)
if(new_level >= 0) {
debug_level = new_level;
}
return true;
}
@ -100,12 +106,15 @@ bool control_h(connection_t *c, const char *request) {
char name[MAX_STRING_SIZE];
bool found = false;
if(sscanf(request, "%*d %*d " MAX_STRING, name) != 1)
if(sscanf(request, "%*d %*d " MAX_STRING, name) != 1) {
return control_return(c, REQ_DISCONNECT, -1);
}
for list_each(connection_t, other, connection_list) {
if(strcmp(other->name, name))
if(strcmp(other->name, name)) {
continue;
}
terminate_connection(other, other->edge);
found = true;
}
@ -134,8 +143,8 @@ bool control_h(connection_t *c, const char *request) {
}
bool init_control(void) {
randomize(controlcookie, sizeof controlcookie / 2);
bin2hex(controlcookie, controlcookie, sizeof controlcookie / 2);
randomize(controlcookie, sizeof(controlcookie) / 2);
bin2hex(controlcookie, controlcookie, sizeof(controlcookie) / 2);
mode_t mask = umask(0);
umask(mask | 077);
@ -150,22 +159,25 @@ bool init_control(void) {
// Get the address and port of the first listening socket
char *localhost = NULL;
sockaddr_t sa;
socklen_t len = sizeof sa;
sockaddr_t sa = {0};
socklen_t len = sizeof(sa);
// Make sure we have a valid address, and map 0.0.0.0 and :: to 127.0.0.1 and ::1.
if(getsockname(listen_socket[0].tcp.fd, (struct sockaddr *)&sa, &len)) {
if(getsockname(listen_socket[0].tcp.fd, &sa.sa, &len)) {
xasprintf(&localhost, "127.0.0.1 port %s", myport);
} else {
if(sa.sa.sa_family == AF_INET) {
if(sa.in.sin_addr.s_addr == 0)
if(sa.in.sin_addr.s_addr == 0) {
sa.in.sin_addr.s_addr = htonl(0x7f000001);
}
} else if(sa.sa.sa_family == AF_INET6) {
static const uint8_t zero[16] = {0};
if(!memcmp(sa.in6.sin6_addr.s6_addr, zero, sizeof zero))
if(!memcmp(sa.in6.sin6_addr.s6_addr, zero, sizeof(zero))) {
sa.in6.sin6_addr.s6_addr[15] = 1;
}
}
localhost = sockaddr2hostname(&sa);
}
@ -177,16 +189,21 @@ bool init_control(void) {
#ifndef HAVE_MINGW
int unix_fd = socket(AF_UNIX, SOCK_STREAM, 0);
if(unix_fd < 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "Could not create UNIX socket: %s", sockstrerror(sockerrno));
return false;
}
struct sockaddr_un sa_un;
sa_un.sun_family = AF_UNIX;
strncpy(sa_un.sun_path, unixsocketname, sizeof sa_un.sun_path);
if(connect(unix_fd, (struct sockaddr *)&sa_un, sizeof sa_un) >= 0) {
sa_un.sun_family = AF_UNIX;
strncpy(sa_un.sun_path, unixsocketname, sizeof(sa_un.sun_path));
sa_un.sun_path[sizeof(sa_un.sun_path) - 1] = 0;
if(connect(unix_fd, (struct sockaddr *)&sa_un, sizeof(sa_un)) >= 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "UNIX socket %s is still in use!", unixsocketname);
return false;
}
@ -194,7 +211,7 @@ bool init_control(void) {
unlink(unixsocketname);
umask(mask | 077);
int result = bind(unix_fd, (struct sockaddr *)&sa_un, sizeof sa_un);
int result = bind(unix_fd, (struct sockaddr *)&sa_un, sizeof(sa_un));
umask(mask);
if(result < 0) {

View file

@ -1,3 +1,6 @@
#ifndef TINC_CONTROL_H
#define TINC_CONTROL_H
/*
control.h -- header for control.c.
Copyright (C) 2007 Guus Sliepen <guus@tinc-vpn.org>
@ -17,11 +20,8 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __TINC_CONTROL_H__
#define __TINC_CONTROL_H__
extern bool init_control();
extern void exit_control();
extern bool init_control(void);
extern void exit_control(void);
extern char controlcookie[];
#endif

View file

@ -1,3 +1,6 @@
#ifndef TINC_CONTROL_COMMON_H
#define TINC_CONTROL_COMMON_H
/*
control_protocol.h -- control socket protocol.
Copyright (C) 2007 Scott Lamb <slamb@slamb.org>
@ -18,9 +21,6 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __TINC_CONTROL_PROTOCOL_H__
#define __TINC_CONTROL_PROTOCOL_H__
#include "protocol.h"
enum request_type {

View file

@ -1,3 +1,6 @@
#ifndef TINC_CRYPTO_H
#define TINC_CRYPTO_H
/*
crypto.h -- header for crypto.c
Copyright (C) 2007-2013 Guus Sliepen <guus@tinc-vpn.org>
@ -17,11 +20,8 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __TINC_CRYPTO_H__
#define __TINC_CRYPTO_H__
extern void crypto_init();
extern void crypto_exit();
extern void randomize(void *, size_t);
extern void crypto_init(void);
extern void crypto_exit(void);
extern void randomize(void *buf, size_t buflen);
#endif

View file

@ -38,7 +38,7 @@ int device_fd = -1;
static HANDLE device_handle = INVALID_HANDLE_VALUE;
char *device = NULL;
char *iface = NULL;
static char *device_info = NULL;
static const char *device_info = "Windows tap device";
static pid_t reader_pid;
static int sp[2];
@ -59,8 +59,9 @@ static bool setup_device(void) {
get_config_string(lookup_config(config_tree, "Device"), &device);
get_config_string(lookup_config(config_tree, "Interface"), &iface);
if(device && iface)
if(device && iface) {
logger(LOG_WARNING, "Warning: both Device and Interface specified, results may not be as expected");
}
/* Open registry and look for network adapters */
@ -70,43 +71,50 @@ static bool setup_device(void) {
}
for(i = 0; ; i++) {
len = sizeof adapterid;
if(RegEnumKeyEx(key, i, adapterid, &len, 0, 0, 0, NULL))
len = sizeof(adapterid);
if(RegEnumKeyEx(key, i, adapterid, &len, 0, 0, 0, NULL)) {
break;
}
/* Find out more about this adapter */
snprintf(regpath, sizeof regpath, "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, adapterid);
snprintf(regpath, sizeof(regpath), "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, adapterid);
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2))
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2)) {
continue;
}
len = sizeof adaptername;
len = sizeof(adaptername);
err = RegQueryValueEx(key2, "Name", 0, 0, adaptername, &len);
RegCloseKey(key2);
if(err)
if(err) {
continue;
}
if(device) {
if(!strcmp(device, adapterid)) {
found = true;
break;
} else
} else {
continue;
}
}
if(iface) {
if(!strcmp(iface, adaptername)) {
found = true;
break;
} else
} else {
continue;
}
}
snprintf(tapname, sizeof tapname, USERMODEDEVICEDIR "%s" TAPSUFFIX, adapterid);
snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, adapterid);
device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0);
if(device_handle != INVALID_HANDLE_VALUE) {
CloseHandle(device_handle);
found = true;
@ -121,13 +129,15 @@ static bool setup_device(void) {
return false;
}
if(!device)
if(!device) {
device = xstrdup(adapterid);
}
if(!iface)
if(!iface) {
iface = xstrdup(adaptername);
}
snprintf(tapname, sizeof tapname, USERMODEDEVICEDIR "%s" TAPSUFFIX, device);
snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, device);
/* Now we are going to open this device twice: once for reading and once for writing.
We do this because apparently it isn't possible to check for activity in the select() loop.
@ -151,7 +161,7 @@ static bool setup_device(void) {
/* Get MAC address from tap device */
if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_MAC, mymac.x, sizeof mymac.x, mymac.x, sizeof mymac.x, &len, 0)) {
if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_MAC, mymac.x, sizeof(mymac.x), mymac.x, sizeof(mymac.x), &len, 0)) {
logger(DEBUG_ALWAYS, LOG_ERR, "Could not get MAC address from Windows tap device %s (%s): %s", device, iface, winerror(GetLastError()));
return false;
}
@ -203,13 +213,12 @@ static bool setup_device(void) {
}
read(device_fd, &gelukt, 1);
if(gelukt != 1) {
logger(DEBUG_ALWAYS, LOG_DEBUG, "Tap reader failed!");
return false;
}
device_info = "Windows tap device";
logger(DEBUG_ALWAYS, LOG_INFO, "%s (%s) is a %s", device, iface, device_info);
return true;
@ -218,12 +227,15 @@ static bool setup_device(void) {
static void close_device(void) {
close(sp[0]);
close(sp[1]);
CloseHandle(device_handle); device_handle = INVALID_HANDLE_VALUE;
CloseHandle(device_handle);
device_handle = INVALID_HANDLE_VALUE;
kill(reader_pid, SIGKILL);
free(device); device = NULL;
free(iface); iface = NULL;
free(device);
device = NULL;
free(iface);
iface = NULL;
device_info = NULL;
}

View file

@ -1,3 +1,6 @@
#ifndef TINC_DEVICE_H
#define TINC_DEVICE_H
/*
device.h -- generic header for device.c
Copyright (C) 2001-2005 Ivo Timmermans
@ -18,9 +21,6 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __TINC_DEVICE_H__
#define __TINC_DEVICE_H__
#include "net.h"
extern int device_fd;
@ -45,4 +45,4 @@ extern const devops_t uml_devops;
extern const devops_t vde_devops;
extern devops_t devops;
#endif /* __TINC_DEVICE_H__ */
#endif

View file

@ -1,3 +1,6 @@
#ifndef TINC_DIGEST_H
#define TINC_DIGEST_H
/*
digest.h -- header file digest.c
Copyright (C) 2007-2016 Guus Sliepen <guus@tinc-vpn.org>
@ -17,9 +20,6 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __TINC_DIGEST_H__
#define __TINC_DIGEST_H__
#define DIGEST_MAX_SIZE 64
#ifndef DISABLE_LEGACY
@ -28,14 +28,14 @@ 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 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__));
extern bool digest_set_key(digest_t *, const void *key, size_t len) __attribute__ ((__warn_unused_result__));
extern int digest_get_nid(const digest_t *);
extern size_t digest_keylength(const digest_t *);
extern size_t digest_length(const digest_t *);
extern bool digest_active(const digest_t *);
extern void digest_close(digest_t *digest);
extern bool digest_create(digest_t *digest, const void *indata, size_t inlen, void *outdata) __attribute__((__warn_unused_result__));
extern bool digest_verify(digest_t *digest, const void *indata, size_t inlen, const void *digestdata) __attribute__((__warn_unused_result__));
extern bool digest_set_key(digest_t *digest, const void *key, size_t len) __attribute__((__warn_unused_result__));
extern int digest_get_nid(const digest_t *digest);
extern size_t digest_keylength(const digest_t *digest);
extern size_t digest_length(const digest_t *digest);
extern bool digest_active(const digest_t *digest);
#endif

View file

@ -50,8 +50,9 @@ int daemon(int nochdir, int noclose) {
}
/* If we are the parent, terminate */
if(pid)
if(pid) {
exit(0);
}
/* Detach by becoming the new process group leader */
if(setsid() < 0) {
@ -108,8 +109,9 @@ int vasprintf(char **buf, const char *fmt, va_list ap) {
status = vsnprintf(*buf, len, fmt, aq);
va_end(aq);
if(status >= 0)
if(status >= 0) {
*buf = xrealloc(*buf, status + 1);
}
if(status > len - 1) {
len = status + 1;

View file

@ -1,3 +1,6 @@
#ifndef TINC_DROPIN_H
#define TINC_DROPIN_H
/*
dropin.h -- header file for dropin.c
Copyright (C) 2000-2005 Ivo Timmermans,
@ -18,9 +21,6 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __DROPIN_H__
#define __DROPIN_H__
#ifndef HAVE_DAEMON
extern int daemon(int, int);
#endif
@ -67,4 +67,4 @@ extern int nanosleep(const struct timespec *req, struct timespec *rem);
#define EAI_SYSTEM 0
#endif
#endif /* __DROPIN_H__ */
#endif

View file

@ -22,12 +22,13 @@
#include "device.h"
#include "logger.h"
#include "net.h"
#include "xalloc.h"
static char *device_info = "dummy device";
static const char *device_info = "dummy device";
static bool setup_device(void) {
device = "dummy";
iface = "dummy";
device = xstrdup("dummy");
iface = xstrdup("dummy");
logger(DEBUG_ALWAYS, LOG_INFO, "%s (%s) is a %s", device, iface, device_info);
return true;
}
@ -36,10 +37,12 @@ static void close_device(void) {
}
static bool read_packet(vpn_packet_t *packet) {
(void)packet;
return false;
}
static bool write_packet(vpn_packet_t *packet) {
(void)packet;
return true;
}

View file

@ -1,3 +1,6 @@
#ifndef TINC_ECDH_H
#define TINC_ECDH_H
/*
ecdh.h -- header file for ecdh.c
Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org>
@ -17,13 +20,10 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __TINC_ECDH_H__
#define __TINC_ECDH_H__
#define ECDH_SIZE 32
#define ECDH_SHARED_SIZE 32
#ifndef __TINC_ECDH_INTERNAL__
#ifndef TINC_ECDH_INTERNAL
typedef struct ecdh ecdh_t;
#endif

View file

@ -1,3 +1,6 @@
#ifndef TINC_ECDSA_H
#define TINC_ECDSA_H
/*
ecdsa.h -- ECDSA key handling
Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org>
@ -17,10 +20,7 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __TINC_ECDSA_H__
#define __TINC_ECDSA_H__
#ifndef __TINC_ECDSA_INTERNAL__
#ifndef TINC_ECDSA_INTERNAL
typedef struct ecdsa ecdsa_t;
#endif

View file

@ -1,3 +1,6 @@
#ifndef TINC_ECDSAGEN_H
#define TINC_ECDSAGEN_H
/*
ecdsagen.h -- ECDSA key generation and export
Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org>
@ -17,9 +20,6 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __TINC_ECDSAGEN_H__
#define __TINC_ECDSAGEN_H__
#include "ecdsa.h"
extern ecdsa_t *ecdsa_generate(void) __attribute__((__malloc__));

View file

@ -21,7 +21,7 @@
#include "ed25519.h"
#define __TINC_ECDH_INTERNAL__
#define TINC_ECDH_INTERNAL
typedef struct ecdh_t {
uint8_t private[64];
} ecdh_t;
@ -31,10 +31,10 @@ typedef struct ecdh_t {
#include "../xalloc.h"
ecdh_t *ecdh_generate_public(void *pubkey) {
ecdh_t *ecdh = xzalloc(sizeof *ecdh);
ecdh_t *ecdh = xzalloc(sizeof(*ecdh));
uint8_t seed[32];
randomize(seed, sizeof seed);
randomize(seed, sizeof(seed));
ed25519_create_keypair(pubkey, ecdh->private, seed);
return ecdh;

View file

@ -21,7 +21,7 @@
#include "ed25519.h"
#define __TINC_ECDSA_INTERNAL__
#define TINC_ECDSA_INTERNAL
typedef struct {
uint8_t private[64];
uint8_t public[32];
@ -42,8 +42,9 @@ ecdsa_t *ecdsa_set_base64_public_key(const char *p) {
return 0;
}
ecdsa_t *ecdsa = xzalloc(sizeof *ecdsa);
ecdsa_t *ecdsa = xzalloc(sizeof(*ecdsa));
len = b64decode(p, ecdsa->public, len);
if(len != 32) {
logger(DEBUG_ALWAYS, LOG_ERR, "Invalid format of public key! len = %d", len);
free(ecdsa);
@ -55,33 +56,40 @@ ecdsa_t *ecdsa_set_base64_public_key(const char *p) {
char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) {
char *base64 = xmalloc(44);
b64encode(ecdsa->public, base64, sizeof ecdsa->public);
b64encode(ecdsa->public, base64, sizeof(ecdsa->public));
return base64;
}
// Read PEM ECDSA keys
static bool read_pem(FILE *fp, const char *type, void *buf, size_t size) {
static bool read_pem(FILE *fp, const char *type, void *vbuf, size_t size) {
char line[1024];
bool data = false;
size_t typelen = strlen(type);
char *buf = vbuf;
while(fgets(line, sizeof line, fp)) {
while(fgets(line, sizeof(line), fp)) {
if(!data) {
if(strncmp(line, "-----BEGIN ", 11))
if(strncmp(line, "-----BEGIN ", 11)) {
continue;
if(strncmp(line + 11, type, typelen))
}
if(strncmp(line + 11, type, typelen)) {
continue;
}
data = true;
continue;
}
if(!strncmp(line, "-----END ", 9))
if(!strncmp(line, "-----END ", 9)) {
break;
}
size_t linelen = strcspn(line, "\r\n");
size_t len = b64decode(line, line, linelen);
if(!len) {
logger(DEBUG_ALWAYS, LOG_ERR, "Invalid base64 data in PEM file\n");
errno = EINVAL;
@ -106,6 +114,7 @@ static bool read_pem(FILE *fp, const char *type, void *buf, size_t size) {
} else {
errno = ENOENT;
}
return false;
}
@ -113,22 +122,29 @@ static bool read_pem(FILE *fp, const char *type, void *buf, size_t size) {
}
ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) {
ecdsa_t *ecdsa = xzalloc(sizeof *ecdsa);
if(read_pem(fp, "ED25519 PUBLIC KEY", ecdsa->public, sizeof ecdsa->public))
ecdsa_t *ecdsa = xzalloc(sizeof(*ecdsa));
if(read_pem(fp, "ED25519 PUBLIC KEY", ecdsa->public, sizeof(ecdsa->public))) {
return ecdsa;
}
free(ecdsa);
return 0;
}
ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) {
ecdsa_t *ecdsa = xmalloc(sizeof *ecdsa);
if(read_pem(fp, "ED25519 PRIVATE KEY", ecdsa->private, sizeof *ecdsa))
ecdsa_t *ecdsa = xmalloc(sizeof(*ecdsa));
if(read_pem(fp, "ED25519 PRIVATE KEY", ecdsa->private, sizeof(*ecdsa))) {
return ecdsa;
}
free(ecdsa);
return 0;
}
size_t ecdsa_size(ecdsa_t *ecdsa) {
(void)ecdsa;
return 64;
}

View file

@ -21,7 +21,7 @@
#include "ed25519.h"
#define __TINC_ECDSA_INTERNAL__
#define TINC_ECDSA_INTERNAL
typedef struct {
uint8_t private[64];
uint8_t public[32];
@ -35,10 +35,10 @@ typedef struct {
// Generate ECDSA key
ecdsa_t *ecdsa_generate(void) {
ecdsa_t *ecdsa = xzalloc(sizeof *ecdsa);
ecdsa_t *ecdsa = xzalloc(sizeof(*ecdsa));
uint8_t seed[32];
randomize(seed, sizeof seed);
randomize(seed, sizeof(seed));
ed25519_create_keypair(ecdsa->public, ecdsa->private, seed);
return ecdsa;
@ -46,10 +46,12 @@ ecdsa_t *ecdsa_generate(void) {
// Write PEM ECDSA keys
static bool write_pem(FILE *fp, const char *type, void *buf, size_t size) {
static bool write_pem(FILE *fp, const char *type, void *vbuf, size_t size) {
fprintf(fp, "-----BEGIN %s-----\n", type);
char *buf = vbuf;
char base64[65];
while(size) {
size_t todo = size > 48 ? 48 : size;
b64encode(buf, base64, todo);
@ -63,9 +65,9 @@ static bool write_pem(FILE *fp, const char *type, void *buf, size_t size) {
}
bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp) {
return write_pem(fp, "ED25519 PUBLIC KEY", ecdsa->public, sizeof ecdsa->public);
return write_pem(fp, "ED25519 PUBLIC KEY", ecdsa->public, sizeof(ecdsa->public));
}
bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp) {
return write_pem(fp, "ED25519 PRIVATE KEY", ecdsa->private, sizeof *ecdsa);
return write_pem(fp, "ED25519 PRIVATE KEY", ecdsa->private, sizeof(*ecdsa));
}

View file

@ -808,17 +808,37 @@ void fe_mul121666(fe h, fe f) {
int64_t carry8;
int64_t carry9;
carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= shl64(carry9, 25);
carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= shl64(carry1, 25);
carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= shl64(carry3, 25);
carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= shl64(carry5, 25);
carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= shl64(carry7, 25);
carry9 = (h9 + (int64_t)(1 << 24)) >> 25;
h0 += carry9 * 19;
h9 -= shl64(carry9, 25);
carry1 = (h1 + (int64_t)(1 << 24)) >> 25;
h2 += carry1;
h1 -= shl64(carry1, 25);
carry3 = (h3 + (int64_t)(1 << 24)) >> 25;
h4 += carry3;
h3 -= shl64(carry3, 25);
carry5 = (h5 + (int64_t)(1 << 24)) >> 25;
h6 += carry5;
h5 -= shl64(carry5, 25);
carry7 = (h7 + (int64_t)(1 << 24)) >> 25;
h8 += carry7;
h7 -= shl64(carry7, 25);
carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= shl64(carry0, 26);
carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= shl64(carry2, 26);
carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= shl64(carry4, 26);
carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= shl64(carry6, 26);
carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= shl64(carry8, 26);
carry0 = (h0 + (int64_t)(1 << 25)) >> 26;
h1 += carry0;
h0 -= shl64(carry0, 26);
carry2 = (h2 + (int64_t)(1 << 25)) >> 26;
h3 += carry2;
h2 -= shl64(carry2, 26);
carry4 = (h4 + (int64_t)(1 << 25)) >> 26;
h5 += carry4;
h4 -= shl64(carry4, 26);
carry6 = (h6 + (int64_t)(1 << 25)) >> 26;
h7 += carry6;
h6 -= shl64(carry6, 26);
carry8 = (h8 + (int64_t)(1 << 25)) >> 26;
h9 += carry8;
h8 -= shl64(carry8, 26);
h[0] = h0;
h[1] = h1;

View file

@ -1,12 +1,12 @@
#ifndef TINC_FIXEDINT_H
#define TINC_FIXEDINT_H
/*
Portable header to provide the 32 and 64 bits type.
Not a compatible replacement for <stdint.h>, do not blindly use it as such.
*/
#ifndef __TINC_FIXEDINT_H__
#define __TINC_FIXEDINT_H__
#if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined(__WATCOMC__) && (defined(_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_) || defined(__UINT_FAST64_TYPE__)) )) && !defined(FIXEDINT_H_INCLUDED)
#include <stdint.h>
#define FIXEDINT_H_INCLUDED

View file

@ -41,6 +41,7 @@ void ed25519_key_exchange(unsigned char *shared_secret, const unsigned char *pub
fe_1(z3);
swap = 0;
for(pos = 254; pos >= 0; --pos) {
b = e[pos / 8] >> (pos & 7);
b &= 1;

View file

@ -88,8 +88,7 @@ static const uint64_t K[80] = {
#endif
/* compress 1024-bits */
static int sha512_compress(sha512_context *md, const unsigned char *buf)
{
static int sha512_compress(sha512_context *md, const unsigned char *buf) {
uint64_t S[8], W[80], t0, t1;
int i;
@ -145,7 +144,9 @@ static int sha512_compress(sha512_context *md, const unsigned char *buf)
@return 0 if successful
*/
int sha512_init(sha512_context *md) {
if (md == NULL) return 1;
if(md == NULL) {
return 1;
}
md->curlen = 0;
md->length = 0;
@ -168,22 +169,30 @@ int sha512_init(sha512_context * md) {
@param inlen The length of the data (octets)
@return 0 if successful
*/
int sha512_update(sha512_context *md, const void *vin, size_t inlen)
{
int sha512_update(sha512_context *md, const void *vin, size_t inlen) {
const unsigned char *in = vin;
size_t n;
size_t i;
int err;
if (md == NULL) return 1;
if (in == NULL) return 1;
if(md == NULL) {
return 1;
}
if(in == NULL) {
return 1;
}
if(md->curlen > sizeof(md->buf)) {
return 1;
}
while(inlen > 0) {
if(md->curlen == 0 && inlen >= 128) {
if((err = sha512_compress(md, in)) != 0) {
return err;
}
md->length += 128 * 8;
in += 128;
inlen -= 128;
@ -198,15 +207,18 @@ int sha512_update(sha512_context *md, const void *vin, size_t inlen)
md->curlen += n;
in += n;
inlen -= n;
if(md->curlen == 128) {
if((err = sha512_compress(md, md->buf)) != 0) {
return err;
}
md->length += 8 * 128;
md->curlen = 0;
}
}
}
return 0;
}
@ -216,13 +228,17 @@ int sha512_update(sha512_context *md, const void *vin, size_t inlen)
@param out [out] The destination of the hash (64 bytes)
@return 0 if successful
*/
int sha512_final(sha512_context * md, void *vout)
{
int sha512_final(sha512_context *md, void *vout) {
int i;
unsigned char *out = vout;
if (md == NULL) return 1;
if (out == NULL) return 1;
if(md == NULL) {
return 1;
}
if(out == NULL) {
return 1;
}
if(md->curlen >= sizeof(md->buf)) {
return 1;
@ -242,6 +258,7 @@ int sha512_final(sha512_context * md, void *vout)
while(md->curlen < 128) {
md->buf[md->curlen++] = (unsigned char)0;
}
sha512_compress(md, md->buf);
md->curlen = 0;
}
@ -266,12 +283,21 @@ int sha512_final(sha512_context * md, void *vout)
return 0;
}
int sha512(const void *message, size_t message_len, void *out)
{
int sha512(const void *message, size_t message_len, void *out) {
sha512_context ctx;
int ret;
if ((ret = sha512_init(&ctx))) return ret;
if ((ret = sha512_update(&ctx, message, message_len))) return ret;
if ((ret = sha512_final(&ctx, out))) return ret;
if((ret = sha512_init(&ctx))) {
return ret;
}
if((ret = sha512_update(&ctx, message, message_len))) {
return ret;
}
if((ret = sha512_final(&ctx, out))) {
return ret;
}
return 0;
}

View file

@ -40,13 +40,15 @@ static int edge_weight_compare(const edge_t *a, const edge_t *b) {
result = a->weight - b->weight;
if(result)
if(result) {
return result;
}
result = strcmp(a->from->name, b->from->name);
if(result)
if(result) {
return result;
}
return strcmp(a->to->name, b->to->name);
}
@ -86,13 +88,15 @@ void edge_add(edge_t *e) {
e->reverse = lookup_edge(e->to, e->from);
if(e->reverse)
if(e->reverse) {
e->reverse->reverse = e;
}
}
void edge_del(edge_t *e) {
if(e->reverse)
if(e->reverse) {
e->reverse->reverse = NULL;
}
splay_delete(edge_weight_tree, e);
splay_delete(e->from->edge_tree, e);

View file

@ -1,3 +1,6 @@
#ifndef TINC_EDGE_H
#define TINC_EDGE_H
/*
edge.h -- header for edge.c
Copyright (C) 2001-2012 Guus Sliepen <guus@tinc-vpn.org>,
@ -18,9 +21,6 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __TINC_EDGE_H__
#define __TINC_EDGE_H__
#include "splay_tree.h"
#include "connection.h"
#include "net.h"
@ -44,12 +44,12 @@ extern splay_tree_t *edge_weight_tree; /* Tree with all known edges sor
extern void init_edges(void);
extern void exit_edges(void);
extern edge_t *new_edge(void) __attribute__((__malloc__));
extern void free_edge(edge_t *);
extern void free_edge(edge_t *e);
extern splay_tree_t *new_edge_tree(void) __attribute__((__malloc__));
extern void free_edge_tree(splay_tree_t *);
extern void edge_add(edge_t *);
extern void edge_del(edge_t *);
extern edge_t *lookup_edge(struct node_t *, struct node_t *);
extern bool dump_edges(struct connection_t *);
extern void free_edge_tree(splay_tree_t *edge_tree);
extern void edge_add(edge_t *e);
extern void edge_del(edge_t *e);
extern edge_t *lookup_edge(struct node_t *from, struct node_t *to);
extern bool dump_edges(struct connection_t *c);
#endif /* __TINC_EDGE_H__ */
#endif

View file

@ -1,3 +1,6 @@
#ifndef TINC_ETHERNET_H
#define TINC_ETHERNET_H
/*
ethernet.h -- missing Ethernet related definitions
Copyright (C) 2005 Ivo Timmermans
@ -18,9 +21,6 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __TINC_ETHERNET_H__
#define __TINC_ETHERNET_H__
#ifndef ETH_ALEN
#define ETH_ALEN 6
#endif
@ -99,4 +99,4 @@ struct ether_arp {
#define arp_op ea_hdr.ar_op
#endif
#endif /* __TINC_ETHERNET_H__ */
#endif

View file

@ -41,25 +41,47 @@ static int io_compare(const io_t *a, const io_t *b) {
#ifndef HAVE_MINGW
return a->fd - b->fd;
#else
return a->event - b->event;
if(a->event < b->event) {
return -1;
}
if(a->event > b->event) {
return 1;
}
return 0;
#endif
}
static int timeout_compare(const timeout_t *a, const timeout_t *b) {
struct timeval diff;
timersub(&a->tv, &b->tv, &diff);
if(diff.tv_sec < 0)
if(diff.tv_sec < 0) {
return -1;
if(diff.tv_sec > 0)
}
if(diff.tv_sec > 0) {
return 1;
if(diff.tv_usec < 0)
}
if(diff.tv_usec < 0) {
return -1;
if(diff.tv_usec > 0)
}
if(diff.tv_usec > 0) {
return 1;
if(a < b)
}
if(a < b) {
return -1;
if(a > b)
}
if(a > b) {
return 1;
}
return 0;
}
@ -67,16 +89,21 @@ static splay_tree_t io_tree = {.compare = (splay_compare_t)io_compare};
static splay_tree_t timeout_tree = {.compare = (splay_compare_t)timeout_compare};
void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags) {
if(io->cb)
if(io->cb) {
return;
}
io->fd = fd;
#ifdef HAVE_MINGW
if(io->fd != -1) {
io->event = WSACreateEvent();
if (io->event == WSA_INVALID_EVENT)
if(io->event == WSA_INVALID_EVENT) {
abort();
}
}
event_count++;
#endif
io->cb = cb;
@ -85,9 +112,10 @@ void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags) {
io_set(io, flags);
if(!splay_insert_node(&io_tree, &io->node))
if(!splay_insert_node(&io_tree, &io->node)) {
abort();
}
}
#ifdef HAVE_MINGW
void io_add_event(io_t *io, io_cb_t cb, void *data, WSAEVENT event) {
@ -97,41 +125,60 @@ void io_add_event(io_t *io, io_cb_t cb, void *data, WSAEVENT event) {
#endif
void io_set(io_t *io, int flags) {
if (flags == io->flags)
if(flags == io->flags) {
return;
}
io->flags = flags;
if (io->fd == -1)
if(io->fd == -1) {
return;
}
#ifndef HAVE_MINGW
if(flags & IO_READ)
FD_SET(io->fd, &readfds);
else
FD_CLR(io->fd, &readfds);
if(flags & IO_WRITE)
if(flags & IO_READ) {
FD_SET(io->fd, &readfds);
} else {
FD_CLR(io->fd, &readfds);
}
if(flags & IO_WRITE) {
FD_SET(io->fd, &writefds);
else
} else {
FD_CLR(io->fd, &writefds);
}
#else
long events = 0;
if (flags & IO_WRITE)
if(flags & IO_WRITE) {
events |= WRITE_EVENTS;
if (flags & IO_READ)
}
if(flags & IO_READ) {
events |= READ_EVENTS;
if (WSAEventSelect(io->fd, io->event, events) != 0)
}
if(WSAEventSelect(io->fd, io->event, events) != 0) {
abort();
}
#endif
}
void io_del(io_t *io) {
if(!io->cb)
if(!io->cb) {
return;
}
io_set(io, 0);
#ifdef HAVE_MINGW
if (io->fd != -1 && WSACloseEvent(io->event) == FALSE)
if(io->fd != -1 && WSACloseEvent(io->event) == FALSE) {
abort();
}
event_count--;
#endif
@ -148,25 +195,31 @@ void timeout_add(timeout_t *timeout, timeout_cb_t cb, void *data, struct timeval
}
void timeout_set(timeout_t *timeout, struct timeval *tv) {
if(timerisset(&timeout->tv))
if(timerisset(&timeout->tv)) {
splay_unlink_node(&timeout_tree, &timeout->node);
}
if(!now.tv_sec)
if(!now.tv_sec) {
gettimeofday(&now, NULL);
}
timeradd(&now, tv, &timeout->tv);
if(!splay_insert_node(&timeout_tree, &timeout->node))
if(!splay_insert_node(&timeout_tree, &timeout->node)) {
abort();
}
}
void timeout_del(timeout_t *timeout) {
if(!timeout->cb)
if(!timeout->cb) {
return;
}
splay_unlink_node(&timeout_tree, &timeout->node);
timeout->cb = 0;
timeout->tv = (struct timeval){0, 0};
timeout->tv = (struct timeval) {
0, 0
};
}
#ifndef HAVE_MINGW
@ -184,41 +237,54 @@ static void signal_handler(int signum) {
}
static void signalio_handler(void *data, int flags) {
(void)data;
(void)flags;
unsigned char signum;
if(read(pipefd[0], &signum, 1) != 1)
return;
signal_t *sig = splay_search(&signal_tree, &((signal_t){.signum = signum}));
if(sig)
if(read(pipefd[0], &signum, 1) != 1) {
return;
}
signal_t *sig = splay_search(&signal_tree, &((signal_t) {
.signum = signum
}));
if(sig) {
sig->cb(sig->data);
}
}
static void pipe_init(void) {
if(!pipe(pipefd))
if(!pipe(pipefd)) {
io_add(&signalio, signalio_handler, NULL, pipefd[0], IO_READ);
}
}
void signal_add(signal_t *sig, signal_cb_t cb, void *data, int signum) {
if(sig->cb)
if(sig->cb) {
return;
}
sig->cb = cb;
sig->data = data;
sig->signum = signum;
sig->node.data = sig;
if(pipefd[0] == -1)
if(pipefd[0] == -1) {
pipe_init();
}
signal(sig->signum, signal_handler);
if(!splay_insert_node(&signal_tree, &sig->node))
if(!splay_insert_node(&signal_tree, &sig->node)) {
abort();
}
}
void signal_del(signal_t *sig) {
if(!sig->cb)
if(!sig->cb) {
return;
}
signal(sig->signum, SIG_DFL);
@ -237,8 +303,10 @@ static struct timeval * get_time_remaining(struct timeval *diff) {
if(diff->tv_sec < 0) {
timeout->cb(timeout->data);
if(timercmp(&timeout->tv, &now, <))
if(timercmp(&timeout->tv, &now, <)) {
timeout_del(timeout);
}
} else {
tv = diff;
break;
@ -258,8 +326,8 @@ bool event_loop(void) {
while(running) {
struct timeval diff;
struct timeval *tv = get_time_remaining(&diff);
memcpy(&readable, &readfds, sizeof readable);
memcpy(&writable, &writefds, sizeof writable);
memcpy(&readable, &readfds, sizeof(readable));
memcpy(&writable, &writefds, sizeof(writable));
int fds = 0;
@ -271,33 +339,42 @@ bool event_loop(void) {
int n = select(fds, &readable, &writable, NULL, tv);
if(n < 0) {
if(sockwouldblock(sockerrno))
if(sockwouldblock(sockerrno)) {
continue;
else
} else {
return false;
}
}
if(!n)
if(!n) {
continue;
}
unsigned int curgen = io_tree.generation;
for splay_each(io_t, io, &io_tree) {
if(FD_ISSET(io->fd, &writable))
if(FD_ISSET(io->fd, &writable)) {
io->cb(io->data, IO_WRITE);
else if(FD_ISSET(io->fd, &readable))
} else if(FD_ISSET(io->fd, &readable)) {
io->cb(io->data, IO_READ);
else
} else {
continue;
}
/*
There are scenarios in which the callback will remove another io_t from the tree
(e.g. closing a double connection). Since splay_each does not support that, we
need to exit the loop now. That's okay, since any remaining events will get picked
up by the next select() call.
need to exit the loop if that happens. That's okay, since any remaining events will
get picked up by the next select() call.
*/
if(curgen != io_tree.generation) {
break;
}
}
}
#else
while(running) {
struct timeval diff;
struct timeval *tv = get_time_remaining(&diff);
@ -318,54 +395,90 @@ bool event_loop(void) {
Note that technically FD_CLOSE has the same problem, but it's okay because user code does not rely on
this event being fired again if ignored.
*/
io_t* writeable_io = NULL;
for splay_each(io_t, io, &io_tree)
unsigned int curgen = io_tree.generation;
for splay_each(io_t, io, &io_tree) {
if(io->flags & IO_WRITE && send(io->fd, NULL, 0, 0) == 0) {
writeable_io = io;
io->cb(io->data, IO_WRITE);
if(curgen != io_tree.generation) {
break;
}
if (writeable_io) {
writeable_io->cb(writeable_io->data, IO_WRITE);
continue;
}
}
WSAEVENT* events = xmalloc(event_count * sizeof(*events));
if(event_count > WSA_MAXIMUM_WAIT_EVENTS) {
WSASetLastError(WSA_INVALID_PARAMETER);
return(false);
}
WSAEVENT events[WSA_MAXIMUM_WAIT_EVENTS];
io_t *io_map[WSA_MAXIMUM_WAIT_EVENTS];
DWORD event_index = 0;
for splay_each(io_t, io, &io_tree) {
events[event_index] = io->event;
io_map[event_index] = io;
event_index++;
}
DWORD result = WSAWaitForMultipleEvents(event_count, events, FALSE, timeout_ms, FALSE);
/*
* If the generation number changes due to event addition
* or removal by a callback we restart the loop.
*/
curgen = io_tree.generation;
WSAEVENT event;
if (result >= WSA_WAIT_EVENT_0 && result < WSA_WAIT_EVENT_0 + event_count)
event = events[result - WSA_WAIT_EVENT_0];
free(events);
if (result == WSA_WAIT_TIMEOUT)
continue;
if (result < WSA_WAIT_EVENT_0 || result >= WSA_WAIT_EVENT_0 + event_count)
return false;
for(DWORD event_offset = 0; event_offset < event_count;) {
DWORD result = WSAWaitForMultipleEvents(event_count - event_offset, &events[event_offset], FALSE, timeout_ms, FALSE);
io_t *io = splay_search(&io_tree, &((io_t){.event = event}));
if (!io)
abort();
if(result == WSA_WAIT_TIMEOUT) {
break;
}
if(result < WSA_WAIT_EVENT_0 || result >= WSA_WAIT_EVENT_0 + event_count - event_offset) {
return(false);
}
/* Look up io in the map by index. */
event_index = result - WSA_WAIT_EVENT_0 + event_offset;
io_t *io = io_map[event_index];
if(io->fd == -1) {
io->cb(io->data, 0);
if(curgen != io_tree.generation) {
break;
}
} else {
WSANETWORKEVENTS network_events;
if (WSAEnumNetworkEvents(io->fd, io->event, &network_events) != 0)
return false;
if (network_events.lNetworkEvents & READ_EVENTS)
if(WSAEnumNetworkEvents(io->fd, io->event, &network_events) != 0) {
return(false);
}
if(network_events.lNetworkEvents & READ_EVENTS) {
io->cb(io->data, IO_READ);
if(curgen != io_tree.generation) {
break;
}
}
/*
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.
*/
}
/* Continue checking the rest of the events. */
event_offset = event_index + 1;
/* Just poll the next time through. */
timeout_ms = 0;
}
}
#endif
return true;

View file

@ -1,3 +1,6 @@
#ifndef TINC_EVENT_H
#define TINC_EVENT_H
/*
event.h -- I/O, timeout and signal event handling
Copyright (C) 2012-2013 Guus Sliepen <guus@tinc-vpn.org>
@ -17,9 +20,6 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __TINC_EVENT_H__
#define __TINC_EVENT_H__
#include "splay_tree.h"
#define IO_READ 1

View file

@ -85,12 +85,14 @@ static inline void set_etherheader(vpn_packet_t *packet, uint16_t ethertype) {
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;

View file

@ -32,31 +32,43 @@
#include "utils.h"
static bool ask_fix(void) {
if(force)
if(force) {
return true;
if(!tty)
}
if(!tty) {
return false;
}
again:
fprintf(stderr, "Fix y/n? ");
char buf[1024];
if(!fgets(buf, sizeof buf, stdin)) {
if(!fgets(buf, sizeof(buf), stdin)) {
tty = false;
return false;
}
if(buf[0] == 'y' || buf[0] == 'Y')
if(buf[0] == 'y' || buf[0] == 'Y') {
return true;
if(buf[0] == 'n' || buf[0] == 'N')
}
if(buf[0] == 'n' || buf[0] == 'N') {
return false;
}
goto again;
}
static void print_tinc_cmd(const char *argv0, const char *format, ...) {
if(confbasegiven)
if(confbasegiven) {
fprintf(stderr, "%s -c %s ", argv0, confbase);
else if(netname)
} else if(netname) {
fprintf(stderr, "%s -n %s ", argv0, netname);
else
} else {
fprintf(stderr, "%s ", argv0);
}
va_list va;
va_start(va, format);
vfprintf(stderr, format, va);
@ -67,13 +79,19 @@ static void print_tinc_cmd(const char *argv0, const char *format, ...) {
static int strtailcmp(const char *str, const char *tail) {
size_t slen = strlen(str);
size_t tlen = strlen(tail);
if(tlen > slen)
if(tlen > slen) {
return -1;
}
return memcmp(str + slen - tlen, tail, tlen);
}
static void check_conffile(const char *fname, bool server) {
(void)server;
FILE *f = fopen(fname, "r");
if(!f) {
fprintf(stderr, "ERROR: cannot read %s: %s\n", fname, strerror(errno));
return;
@ -84,12 +102,14 @@ static void check_conffile(const char *fname, bool server) {
bool skip = false;
const int maxvariables = 50;
int count[maxvariables];
memset(count, 0, sizeof count);
memset(count, 0, sizeof(count));
while(fgets(line, sizeof line, f)) {
while(fgets(line, sizeof(line), f)) {
if(skip) {
if(!strncmp(line, "-----END", 8))
if(!strncmp(line, "-----END", 8)) {
skip = false;
}
continue;
} else {
if(!strncmp(line, "-----BEGIN", 10)) {
@ -105,26 +125,32 @@ static void check_conffile(const char *fname, bool server) {
lineno++;
eol = line + strlen(line);
while(strchr("\t \r\n", *--eol))
*eol = '\0';
if(!line[0] || line[0] == '#')
while(strchr("\t \r\n", *--eol)) {
*eol = '\0';
}
if(!line[0] || line[0] == '#') {
continue;
}
len = strcspn(value, "\t =");
value += len;
value += strspn(value, "\t ");
if(*value == '=') {
value++;
value += strspn(value, "\t ");
}
variable[len] = '\0';
bool found = false;
for(int i = 0; variables[i].name; i++) {
if(strcasecmp(variables[i].name, variable))
if(strcasecmp(variables[i].name, variable)) {
continue;
}
found = true;
@ -132,24 +158,29 @@ static void check_conffile(const char *fname, bool server) {
fprintf(stderr, "WARNING: obsolete variable %s in %s line %d\n", variable, fname, lineno);
}
if(i < maxvariables)
if(i < maxvariables) {
count[i]++;
}
}
if(!found)
if(!found) {
fprintf(stderr, "WARNING: unknown variable %s in %s line %d\n", variable, fname, lineno);
}
if(!*value)
if(!*value) {
fprintf(stderr, "ERROR: no value for variable %s in %s line %d\n", variable, fname, lineno);
}
}
for(int i = 0; variables[i].name && i < maxvariables; i++) {
if(count[i] > 1 && !(variables[i].type & VAR_MULTIPLE))
if(count[i] > 1 && !(variables[i].type & VAR_MULTIPLE)) {
fprintf(stderr, "WARNING: multiple instances of variable %s in %s\n", variables[i].name, fname);
}
}
if(ferror(f))
if(ferror(f)) {
fprintf(stderr, "ERROR: while reading %s: %s\n", fname, strerror(errno));
}
fclose(f);
}
@ -165,19 +196,23 @@ int fsck(const char *argv0) {
if(access(tinc_conf, R_OK)) {
fprintf(stderr, "ERROR: cannot read %s: %s\n", tinc_conf, strerror(errno));
if(errno == ENOENT) {
fprintf(stderr, "No tinc configuration found. Create a new one with:\n\n");
print_tinc_cmd(argv0, "init");
} else if(errno == EACCES) {
if(uid != 0)
if(uid != 0) {
fprintf(stderr, "You are currently not running tinc as root. Use sudo?\n");
else
} else {
fprintf(stderr, "Check the permissions of each component of the path %s.\n", tinc_conf);
}
}
return 1;
}
char *name = get_my_name(true);
if(!name) {
fprintf(stderr, "ERROR: tinc cannot run without a valid Name.\n");
return 1;
@ -192,7 +227,7 @@ int fsck(const char *argv0) {
#ifndef DISABLE_LEGACY
rsa_t *rsa_priv = NULL;
snprintf(fname, sizeof fname, "%s/rsa_key.priv", confbase);
snprintf(fname, sizeof(fname), "%s/rsa_key.priv", confbase);
if(stat(fname, &st)) {
if(errno != ENOENT) {
@ -203,12 +238,15 @@ int fsck(const char *argv0) {
}
} else {
FILE *f = fopen(fname, "r");
if(!f) {
fprintf(stderr, "ERROR: could not open %s: %s\n", fname, strerror(errno));
return 1;
}
rsa_priv = rsa_read_pem_private_key(f);
fclose(f);
if(!rsa_priv) {
fprintf(stderr, "ERROR: No key or unusable key found in %s.\n", fname);
fprintf(stderr, "You can generate a new RSA key with:\n\n");
@ -217,23 +255,28 @@ int fsck(const char *argv0) {
}
#if !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN)
if(st.st_mode & 077) {
fprintf(stderr, "WARNING: unsafe file permissions on %s.\n", fname);
if(st.st_uid != uid) {
fprintf(stderr, "You are not running %s as the same uid as %s.\n", argv0, fname);
} else if(ask_fix()) {
if(chmod(fname, st.st_mode & ~077))
if(chmod(fname, st.st_mode & ~077)) {
fprintf(stderr, "ERROR: could not change permissions of %s: %s\n", fname, strerror(errno));
else
} else {
fprintf(stderr, "Fixed permissions of %s.\n", fname);
}
}
}
#endif
}
#endif
ecdsa_t *ecdsa_priv = NULL;
snprintf(fname, sizeof fname, "%s/ed25519_key.priv", confbase);
snprintf(fname, sizeof(fname), "%s/ed25519_key.priv", confbase);
if(stat(fname, &st)) {
if(errno != ENOENT) {
@ -244,12 +287,15 @@ int fsck(const char *argv0) {
}
} else {
FILE *f = fopen(fname, "r");
if(!f) {
fprintf(stderr, "ERROR: could not open %s: %s\n", fname, strerror(errno));
return 1;
}
ecdsa_priv = ecdsa_read_pem_private_key(f);
fclose(f);
if(!ecdsa_priv) {
fprintf(stderr, "ERROR: No key or unusable key found in %s.\n", fname);
fprintf(stderr, "You can generate a new Ed25519 key with:\n\n");
@ -258,24 +304,30 @@ int fsck(const char *argv0) {
}
#if !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN)
if(st.st_mode & 077) {
fprintf(stderr, "WARNING: unsafe file permissions on %s.\n", fname);
if(st.st_uid != uid) {
fprintf(stderr, "You are not running %s as the same uid as %s.\n", argv0, fname);
} else if(ask_fix()) {
if(chmod(fname, st.st_mode & ~077))
if(chmod(fname, st.st_mode & ~077)) {
fprintf(stderr, "ERROR: could not change permissions of %s: %s\n", fname, strerror(errno));
else
} else {
fprintf(stderr, "Fixed permissions of %s.\n", fname);
}
}
}
#endif
}
#ifdef DISABLE_LEGACY
if(!ecdsa_priv) {
fprintf(stderr, "ERROR: No Ed25519 private key found.\n");
#else
if(!rsa_priv && !ecdsa_priv) {
fprintf(stderr, "ERROR: Neither RSA or Ed25519 private key found.\n");
#endif
@ -287,9 +339,11 @@ int fsck(const char *argv0) {
// Check for public keys.
// TODO: use RSAPublicKeyFile variable if present.
snprintf(fname, sizeof fname, "%s/hosts/%s", confbase, name);
if(access(fname, R_OK))
snprintf(fname, sizeof(fname), "%s/hosts/%s", confbase, name);
if(access(fname, R_OK)) {
fprintf(stderr, "WARNING: cannot read %s\n", fname);
}
FILE *f;
@ -297,6 +351,7 @@ int fsck(const char *argv0) {
rsa_t *rsa_pub = NULL;
f = fopen(fname, "r");
if(f) {
rsa_pub = rsa_read_pem_public_key(f);
fclose(f);
@ -305,13 +360,17 @@ int fsck(const char *argv0) {
if(rsa_priv) {
if(!rsa_pub) {
fprintf(stderr, "WARNING: No (usable) public RSA key found.\n");
if(ask_fix()) {
FILE *f = fopen(fname, "a");
if(f) {
if(rsa_write_pem_public_key(rsa_priv, f))
if(rsa_write_pem_public_key(rsa_priv, f)) {
fprintf(stderr, "Wrote RSA public key to %s.\n", fname);
else
} else {
fprintf(stderr, "ERROR: could not write RSA public key to %s.\n", fname);
}
fclose(f);
} else {
fprintf(stderr, "ERROR: could not append to %s: %s\n", fname, strerror(errno));
@ -320,56 +379,70 @@ int fsck(const char *argv0) {
} else {
// TODO: suggest remedies
size_t len = rsa_size(rsa_priv);
if(len != rsa_size(rsa_pub)) {
fprintf(stderr, "ERROR: public and private RSA keys do not match.\n");
return 1;
}
char buf1[len], buf2[len], buf3[len];
randomize(buf1, sizeof buf1);
randomize(buf1, sizeof(buf1));
buf1[0] &= 0x7f;
memset(buf2, 0, sizeof buf2);
memset(buf3, 0, sizeof buf2);
if(!rsa_public_encrypt(rsa_pub, buf1, sizeof buf1, buf2)) {
memset(buf2, 0, sizeof(buf2));
memset(buf3, 0, sizeof(buf2));
if(!rsa_public_encrypt(rsa_pub, buf1, sizeof(buf1), buf2)) {
fprintf(stderr, "ERROR: public RSA key does not work.\n");
return 1;
}
if(!rsa_private_decrypt(rsa_priv, buf2, sizeof buf2, buf3)) {
if(!rsa_private_decrypt(rsa_priv, buf2, sizeof(buf2), buf3)) {
fprintf(stderr, "ERROR: private RSA key does not work.\n");
return 1;
}
if(memcmp(buf1, buf3, sizeof buf1)) {
if(memcmp(buf1, buf3, sizeof(buf1))) {
fprintf(stderr, "ERROR: public and private RSA keys do not match.\n");
return 1;
}
}
} else {
if(rsa_pub)
if(rsa_pub) {
fprintf(stderr, "WARNING: A public RSA key was found but no private key is known.\n");
}
}
#endif
ecdsa_t *ecdsa_pub = NULL;
f = fopen(fname, "r");
if(f) {
ecdsa_pub = get_pubkey(f);
if(!ecdsa_pub) {
rewind(f);
ecdsa_pub = ecdsa_read_pem_public_key(f);
}
fclose(f);
}
if(ecdsa_priv) {
if(!ecdsa_pub) {
fprintf(stderr, "WARNING: No (usable) public Ed25519 key found.\n");
if(ask_fix()) {
FILE *f = fopen(fname, "a");
if(f) {
if(ecdsa_write_pem_public_key(ecdsa_priv, f))
if(ecdsa_write_pem_public_key(ecdsa_priv, f)) {
fprintf(stderr, "Wrote Ed25519 public key to %s.\n", fname);
else
} else {
fprintf(stderr, "ERROR: could not write Ed25519 public key to %s.\n", fname);
}
fclose(f);
} else {
fprintf(stderr, "ERROR: could not append to %s: %s\n", fname, strerror(errno));
@ -378,104 +451,132 @@ int fsck(const char *argv0) {
} else {
// TODO: suggest remedies
char *key1 = ecdsa_get_base64_public_key(ecdsa_pub);
if(!key1) {
fprintf(stderr, "ERROR: public Ed25519 key does not work.\n");
return 1;
}
char *key2 = ecdsa_get_base64_public_key(ecdsa_priv);
if(!key2) {
free(key1);
fprintf(stderr, "ERROR: private Ed25519 key does not work.\n");
return 1;
}
int result = strcmp(key1, key2);
free(key1);
free(key2);
if(result) {
fprintf(stderr, "ERROR: public and private Ed25519 keys do not match.\n");
return 1;
}
}
} else {
if(ecdsa_pub)
if(ecdsa_pub) {
fprintf(stderr, "WARNING: A public Ed25519 key was found but no private key is known.\n");
}
}
// Check whether scripts are executable
struct dirent *ent;
DIR *dir = opendir(confbase);
if(!dir) {
fprintf(stderr, "ERROR: cannot read directory %s: %s\n", confbase, strerror(errno));
return 1;
}
while((ent = readdir(dir))) {
if(strtailcmp(ent->d_name, "-up") && strtailcmp(ent->d_name, "-down"))
if(strtailcmp(ent->d_name, "-up") && strtailcmp(ent->d_name, "-down")) {
continue;
}
strncpy(fname, ent->d_name, sizeof fname);
strncpy(fname, ent->d_name, sizeof(fname));
char *dash = strrchr(fname, '-');
if(!dash)
if(!dash) {
continue;
}
*dash = 0;
if(strcmp(fname, "tinc") && strcmp(fname, "host") && strcmp(fname, "subnet")) {
static bool explained = false;
fprintf(stderr, "WARNING: Unknown script %s" SLASH "%s found.\n", confbase, ent->d_name);
if(!explained) {
fprintf(stderr, "The only scripts in %s executed by tinc are:\n", confbase);
fprintf(stderr, "tinc-up, tinc-down, host-up, host-down, subnet-up and subnet-down.\n");
explained = true;
}
continue;
}
snprintf(fname, sizeof fname, "%s" SLASH "%s", confbase, ent->d_name);
snprintf(fname, sizeof(fname), "%s" SLASH "%s", confbase, ent->d_name);
if(access(fname, R_OK | X_OK)) {
if(errno != EACCES) {
fprintf(stderr, "ERROR: cannot access %s: %s\n", fname, strerror(errno));
continue;
}
fprintf(stderr, "WARNING: cannot read and execute %s: %s\n", fname, strerror(errno));
if(ask_fix()) {
if(chmod(fname, 0755))
if(chmod(fname, 0755)) {
fprintf(stderr, "ERROR: cannot change permissions on %s: %s\n", fname, strerror(errno));
}
}
}
}
closedir(dir);
snprintf(dname, sizeof dname, "%s" SLASH "hosts", confbase);
snprintf(dname, sizeof(dname), "%s" SLASH "hosts", confbase);
dir = opendir(dname);
if(!dir) {
fprintf(stderr, "ERROR: cannot read directory %s: %s\n", dname, strerror(errno));
return 1;
}
while((ent = readdir(dir))) {
if(strtailcmp(ent->d_name, "-up") && strtailcmp(ent->d_name, "-down"))
if(strtailcmp(ent->d_name, "-up") && strtailcmp(ent->d_name, "-down")) {
continue;
}
strncpy(fname, ent->d_name, sizeof fname);
strncpy(fname, ent->d_name, sizeof(fname));
char *dash = strrchr(fname, '-');
if(!dash)
if(!dash) {
continue;
}
*dash = 0;
snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, ent->d_name);
snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, ent->d_name);
if(access(fname, R_OK | X_OK)) {
if(errno != EACCES) {
fprintf(stderr, "ERROR: cannot access %s: %s\n", fname, strerror(errno));
continue;
}
fprintf(stderr, "WARNING: cannot read and execute %s: %s\n", fname, strerror(errno));
if(ask_fix()) {
if(chmod(fname, 0755))
if(chmod(fname, 0755)) {
fprintf(stderr, "ERROR: cannot change permissions on %s: %s\n", fname, strerror(errno));
}
}
}
}
closedir(dir);
// Check for obsolete / unsafe / unknown configuration variables.
@ -483,14 +584,17 @@ int fsck(const char *argv0) {
check_conffile(tinc_conf, true);
dir = opendir(dname);
if(dir) {
while((ent = readdir(dir))) {
if(!check_id(ent->d_name))
if(!check_id(ent->d_name)) {
continue;
}
snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, ent->d_name);
snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, ent->d_name);
check_conffile(fname, false);
}
closedir(dir);
}

View file

@ -1,3 +1,6 @@
#ifndef TINC_FSCK_H
#define TINC_FSCK_H
/*
fsck.h -- header for fsck.c.
Copyright (C) 2012 Guus Sliepen <guus@tinc-vpn.org>
@ -17,10 +20,6 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __TINC_FSCK_H__
#define __TINC_FSCK_H__
extern int fsck(const char *argv0);
#endif

View file

@ -55,7 +55,7 @@ static struct {
static bool nametocipher(const char *name, int *algo, int *mode) {
size_t i;
for(i = 0; i < sizeof ciphertable / sizeof *ciphertable; i++) {
for(i = 0; i < sizeof(ciphertable) / sizeof(*ciphertable); i++) {
if(ciphertable[i].name && !strcasecmp(name, ciphertable[i].name)) {
*algo = ciphertable[i].algo;
*mode = ciphertable[i].mode;
@ -69,7 +69,7 @@ static bool nametocipher(const char *name, int *algo, int *mode) {
static bool nidtocipher(int nid, int *algo, int *mode) {
size_t i;
for(i = 0; i < sizeof ciphertable / sizeof *ciphertable; i++) {
for(i = 0; i < sizeof(ciphertable) / sizeof(*ciphertable); i++) {
if(nid == ciphertable[i].nid) {
*algo = ciphertable[i].algo;
*mode = ciphertable[i].mode;
@ -83,7 +83,7 @@ static bool nidtocipher(int nid, int *algo, int *mode) {
static bool ciphertonid(int algo, int mode, int *nid) {
size_t i;
for(i = 0; i < sizeof ciphertable / sizeof *ciphertable; i++) {
for(i = 0; i < sizeof(ciphertable) / sizeof(*ciphertable); i++) {
if(algo == ciphertable[i].algo && mode == ciphertable[i].mode) {
*nid = ciphertable[i].nid;
return true;
@ -102,7 +102,7 @@ static bool cipher_open(cipher_t *cipher, int algo, int mode) {
}
if((err = gcry_cipher_open(&cipher->handle, algo, mode, 0))) {
logger(DEBUG_ALWAYS, LOG_DEBUG, "Unable to intialise cipher %d mode %d: %s", algo, mode, gcry_strerror(err));
logger(DEBUG_ALWAYS, LOG_DEBUG, "Unable to initialise cipher %d mode %d: %s", algo, mode, gcry_strerror(err));
return false;
}
@ -146,11 +146,9 @@ void cipher_close(cipher_t *cipher) {
cipher->handle = NULL;
}
if(cipher->key) {
free(cipher->key);
cipher->key = NULL;
}
}
size_t cipher_keylength(const cipher_t *cipher) {
return cipher->keylen + cipher->blklen;
@ -193,8 +191,9 @@ bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou
uint8_t pad[cipher->blklen];
if(cipher->padding) {
if(!oneshot)
if(!oneshot) {
return false;
}
size_t reqlen = ((inlen + cipher->blklen) / cipher->blklen) * cipher->blklen;
@ -207,14 +206,16 @@ bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou
inlen = reqlen - cipher->blklen;
for(int i = 0; i < cipher->blklen; i++)
if(i < cipher->blklen - padbyte)
if(i < cipher->blklen - padbyte) {
pad[i] = ((uint8_t *)indata)[inlen + i];
else
} else {
pad[i] = padbyte;
}
}
if(oneshot)
if(oneshot) {
gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen);
}
if((err = gcry_cipher_encrypt(cipher->handle, outdata, *outlen, indata, inlen))) {
logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: %s", gcry_strerror(err));
@ -237,8 +238,9 @@ bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou
bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) {
gcry_error_t err;
if(oneshot)
if(oneshot) {
gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen);
}
if((err = gcry_cipher_decrypt(cipher->handle, outdata, *outlen, indata, inlen))) {
logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting: %s", gcry_strerror(err));
@ -246,8 +248,9 @@ bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou
}
if(cipher->padding) {
if(!oneshot)
if(!oneshot) {
return false;
}
uint8_t padbyte = ((uint8_t *)outdata)[inlen - 1];
@ -265,8 +268,9 @@ bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou
}
*outlen = origlen;
} else
} else {
*outlen = inlen;
}
return true;
}

View file

@ -37,7 +37,7 @@ static struct {
static bool nametodigest(const char *name, int *algo) {
int i;
for(i = 0; i < sizeof digesttable / sizeof *digesttable; i++) {
for(i = 0; i < sizeof(digesttable) / sizeof(*digesttable); i++) {
if(digesttable[i].name && !strcasecmp(name, digesttable[i].name)) {
*algo = digesttable[i].algo;
return true;
@ -50,7 +50,7 @@ static bool nametodigest(const char *name, int *algo) {
static bool nidtodigest(int nid, int *algo) {
int i;
for(i = 0; i < sizeof digesttable / sizeof *digesttable; i++) {
for(i = 0; i < sizeof(digesttable) / sizeof(*digesttable); i++) {
if(nid == digesttable[i].nid) {
*algo = digesttable[i].algo;
return true;
@ -63,7 +63,7 @@ static bool nidtodigest(int nid, int *algo) {
static bool digesttonid(int algo, int *nid) {
int i;
for(i = 0; i < sizeof digesttable / sizeof *digesttable; i++) {
for(i = 0; i < sizeof(digesttable) / sizeof(*digesttable); i++) {
if(algo == digesttable[i].algo) {
*nid = digesttable[i].nid;
return true;
@ -81,10 +81,11 @@ static bool digest_open(digest_t *digest, int algo, int maclength) {
unsigned int len = gcry_md_get_algo_dlen(algo);
if(maclength > len || maclength < 0)
if(maclength > len || maclength < 0) {
digest->maclength = len;
else
} else {
digest->maclength = maclength;
}
digest->algo = algo;
digest->hmac = NULL;
@ -119,16 +120,21 @@ bool digest_open_sha1(digest_t *digest, int maclength) {
}
void digest_close(digest_t *digest) {
if(digest->hmac)
if(digest->hmac) {
gcry_md_close(digest->hmac);
}
digest->hmac = NULL;
}
bool digest_set_key(digest_t *digest, const void *key, size_t len) {
if(!digest->hmac)
if(!digest->hmac) {
gcry_md_open(&digest->hmac, digest->algo, GCRY_MD_FLAG_HMAC);
if(!digest->hmac)
}
if(!digest->hmac) {
return false;
}
return !gcry_md_setkey(digest->hmac, key, len);
}
@ -141,8 +147,11 @@ bool digest_create(digest_t *digest, const void *indata, size_t inlen, void *out
gcry_md_reset(digest->hmac);
gcry_md_write(digest->hmac, indata, inlen);
tmpdata = gcry_md_read(digest->hmac, digest->algo);
if(!tmpdata)
if(!tmpdata) {
return false;
}
memcpy(outdata, tmpdata, digest->maclength);
} else {
char tmpdata[len];

View file

@ -1,3 +1,6 @@
#ifndef TINC_GCRYPT_DIGEST_H
#define TINC_GCRYPT_DIGEST_H
/*
digest.h -- header file digest.c
Copyright (C) 2007-2009 Guus Sliepen <guus@tinc-vpn.org>
@ -17,9 +20,6 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __TINC_DIGEST_H__
#define __TINC_DIGEST_H__
#include <gcrypt.h>
#define DIGEST_MAX_SIZE 64

View file

@ -23,9 +23,10 @@
#include "../ed25519/sha512.h"
static void memxor(char *buf, char c, size_t len) {
for(size_t i = 0; i < len; i++)
for(size_t i = 0; i < len; i++) {
buf[i] ^= c;
}
}
static const size_t mdlen = 64;
static const size_t blklen = 128;
@ -38,30 +39,39 @@ static bool hmac_sha512(const char *key, size_t keylen, const char *msg, size_t
memcpy(tmp, key, keylen);
memset(tmp + keylen, 0, blklen - keylen);
} else {
if(sha512(key, keylen, tmp) != 0)
if(sha512(key, keylen, tmp) != 0) {
return false;
}
memset(tmp + mdlen, 0, blklen - mdlen);
}
if(sha512_init(&md) != 0)
if(sha512_init(&md) != 0) {
return false;
}
// ipad
memxor(tmp, 0x36, blklen);
if(sha512_update(&md, tmp, blklen) != 0)
if(sha512_update(&md, tmp, blklen) != 0) {
return false;
}
// message
if(sha512_update(&md, msg, msglen) != 0)
if(sha512_update(&md, msg, msglen) != 0) {
return false;
}
if(sha512_final(&md, tmp + blklen) != 0)
if(sha512_final(&md, tmp + blklen) != 0) {
return false;
}
// opad
memxor(tmp, 0x36 ^ 0x5c, blklen);
if(sha512(tmp, sizeof tmp, out) != 0)
if(sha512(tmp, sizeof(tmp), out) != 0) {
return false;
}
return true;
}
@ -84,18 +94,23 @@ bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char
while(outlen > 0) {
/* Inner HMAC */
if(!hmac_sha512(secret, secretlen, data, sizeof data, data))
if(!hmac_sha512(secret, secretlen, data, sizeof(data), data)) {
return false;
}
/* Outer HMAC */
if(outlen >= mdlen) {
if(!hmac_sha512(secret, secretlen, data, sizeof data, out))
if(!hmac_sha512(secret, secretlen, data, sizeof(data), out)) {
return false;
}
out += mdlen;
outlen -= mdlen;
} else {
if(!hmac_sha512(secret, secretlen, data, sizeof data, hash))
if(!hmac_sha512(secret, secretlen, data, sizeof(data), hash)) {
return false;
}
memcpy(out, hash, outlen);
out += outlen;
outlen = 0;

View file

@ -61,12 +61,15 @@ static bool pem_decode(FILE *fp, const char *header, uint8_t *buf, size_t size,
size_t i, j = 0;
while(!feof(fp)) {
if(!fgets(line, sizeof line, fp))
if(!fgets(line, sizeof(line), fp)) {
return false;
}
if(!decode && !strncmp(line, "-----BEGIN ", 11)) {
if(!strncmp(line + 11, header, strlen(header)))
if(!strncmp(line + 11, header, strlen(header))) {
decode = true;
}
continue;
}
@ -74,14 +77,18 @@ static bool pem_decode(FILE *fp, const char *header, uint8_t *buf, size_t size,
break;
}
if(!decode)
if(!decode) {
continue;
}
for(i = 0; line[i] >= ' '; i++) {
if((signed char)line[i] < 0 || b64d[(int)line[i]] == 0xff)
if((signed char)line[i] < 0 || b64d[(int)line[i]] == 0xff) {
break;
}
word |= b64d[(int)line[i]] << shift;
shift -= 6;
if(shift <= 2) {
if(j > size) {
errno = ENOMEM;
@ -95,8 +102,10 @@ static bool pem_decode(FILE *fp, const char *header, uint8_t *buf, size_t size,
}
}
if(outsize)
if(outsize) {
*outsize = j;
}
return true;
}
@ -104,20 +113,25 @@ static bool pem_decode(FILE *fp, const char *header, uint8_t *buf, size_t size,
// BER decoding functions
static int ber_read_id(unsigned char **p, size_t *buflen) {
if(*buflen <= 0)
if(*buflen <= 0) {
return -1;
}
if((**p & 0x1f) == 0x1f) {
int id = 0;
bool more;
while(*buflen > 0) {
id <<= 7;
id |= **p & 0x7f;
more = *(*p)++ & 0x80;
(*buflen)--;
if(!more)
if(!more) {
break;
}
}
return id;
} else {
(*buflen)--;
@ -126,15 +140,18 @@ static int ber_read_id(unsigned char **p, size_t *buflen) {
}
static size_t ber_read_len(unsigned char **p, size_t *buflen) {
if(*buflen <= 0)
if(*buflen <= 0) {
return -1;
}
if(**p & 0x80) {
size_t result = 0;
int len = *(*p)++ & 0x7f;
(*buflen)--;
if(len > *buflen)
if(len > *buflen) {
return 0;
}
while(len--) {
result <<= 8;
@ -155,8 +172,10 @@ static bool ber_read_sequence(unsigned char **p, size_t *buflen, size_t *result)
size_t len = ber_read_len(p, buflen);
if(tag == 0x10) {
if(result)
if(result) {
*result = len;
}
return true;
} else {
return false;
@ -168,11 +187,13 @@ static bool ber_read_mpi(unsigned char **p, size_t *buflen, gcry_mpi_t *mpi) {
size_t len = ber_read_len(p, buflen);
gcry_error_t err = 0;
if(tag != 0x02 || len > *buflen)
if(tag != 0x02 || len > *buflen) {
return false;
}
if(mpi)
if(mpi) {
err = gcry_mpi_scan(mpi, GCRYMPI_FMT_USG, *p, len, NULL);
}
*p += len;
*buflen -= len;
@ -215,7 +236,7 @@ bool rsa_read_pem_public_key(rsa_t *rsa, FILE *fp) {
uint8_t derbuf[8096], *derp = derbuf;
size_t derlen;
if(!pem_decode(fp, "RSA PUBLIC KEY", derbuf, sizeof derbuf, &derlen)) {
if(!pem_decode(fp, "RSA PUBLIC KEY", derbuf, sizeof(derbuf), &derlen)) {
logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA public key: %s", strerror(errno));
return NULL;
}
@ -235,7 +256,7 @@ bool rsa_read_pem_private_key(rsa_t *rsa, FILE *fp) {
uint8_t derbuf[8096], *derp = derbuf;
size_t derlen;
if(!pem_decode(fp, "RSA PRIVATE KEY", derbuf, sizeof derbuf, &derlen)) {
if(!pem_decode(fp, "RSA PRIVATE KEY", derbuf, sizeof(derbuf), &derlen)) {
logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA private key: %s", strerror(errno));
return NULL;
}
@ -277,8 +298,10 @@ bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) {
gcry_mpi_powm(outmpi, inmpi, rsa->e, rsa->n);
int pad = len - (gcry_mpi_get_nbits(outmpi) + 7) / 8;
while(pad--)
while(pad--) {
*(char *)out++ = 0;
}
check(gcry_mpi_print(GCRYMPI_FMT_USG, out, len, NULL, outmpi));
@ -293,8 +316,10 @@ bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) {
gcry_mpi_powm(outmpi, inmpi, rsa->d, rsa->n);
int pad = len - (gcry_mpi_get_nbits(outmpi) + 7) / 8;
while(pad--)
while(pad--) {
*(char *)out++ = 0;
}
check(gcry_mpi_print(GCRYMPI_FMT_USG, out, len, NULL, outmpi));

View file

@ -44,9 +44,11 @@ static bool pem_encode(FILE *fp, const char *header, uint8_t *buf, size_t size)
word = buf[i] << 16 | buf[i + 1] << 8 | buf[i + 2];
} else {
word = buf[i] << 16;
if(i == size - 2)
if(i == size - 2) {
word |= buf[i + 1] << 8;
}
}
line[j++] = b64e[(word >> 18) ];
line[j++] = b64e[(word >> 12) & 0x3f];
@ -62,8 +64,10 @@ static bool pem_encode(FILE *fp, const char *header, uint8_t *buf, size_t size)
}
if(size % 3 > 0) {
if(size % 3 > 1)
if(size % 3 > 1) {
line[j++] = '=';
}
line[j++] = '=';
}
@ -82,19 +86,24 @@ static bool pem_encode(FILE *fp, const char *header, uint8_t *buf, size_t size)
// BER encoding functions
static bool ber_write_id(uint8_t **p, size_t *buflen, int id) {
if(*buflen <= 0)
if(*buflen <= 0) {
return false;
}
if(id >= 0x1f) {
while(id) {
if(*buflen <= 0)
if(*buflen <= 0) {
return false;
}
(*buflen)--;
**p = id & 0x7f;
id >>= 7;
if(id)
if(id) {
**p |= 0x80;
}
(*p)++;
}
} else {
@ -107,14 +116,18 @@ static bool ber_write_id(uint8_t **p, size_t *buflen, int id) {
static bool ber_write_len(uint8_t **p, size_t *buflen, size_t len) {
do {
if(*buflen <= 0)
if(*buflen <= 0) {
return false;
}
(*buflen)--;
**p = len & 0x7f;
len >>= 7;
if(len)
if(len) {
**p |= 0x80;
}
(*p)++;
} while(len);
@ -122,8 +135,9 @@ static bool ber_write_len(uint8_t **p, size_t *buflen, size_t len) {
}
static bool ber_write_sequence(uint8_t **p, size_t *buflen, uint8_t *seqbuf, size_t seqlen) {
if(!ber_write_id(p, buflen, 0x10) || !ber_write_len(p, buflen, seqlen) || *buflen < seqlen)
if(!ber_write_id(p, buflen, 0x10) || !ber_write_len(p, buflen, seqlen) || *buflen < seqlen) {
return false;
}
memcpy(*p, seqbuf, seqlen);
*p += seqlen;
@ -134,15 +148,18 @@ static bool ber_write_sequence(uint8_t **p, size_t *buflen, uint8_t *seqbuf, siz
static bool ber_write_mpi(uint8_t **p, size_t *buflen, gcry_mpi_t mpi) {
uint8_t tmpbuf[1024];
size_t tmplen = sizeof tmpbuf;
size_t tmplen = sizeof(tmpbuf);
gcry_error_t err;
err = gcry_mpi_aprint(GCRYMPI_FMT_USG, &tmpbuf, &tmplen, mpi);
if(err)
return false;
if(!ber_write_id(p, buflen, 0x02) || !ber_write_len(p, buflen, tmplen) || *buflen < tmplen)
if(err) {
return false;
}
if(!ber_write_id(p, buflen, 0x02) || !ber_write_len(p, buflen, tmplen) || *buflen < tmplen) {
return false;
}
memcpy(*p, tmpbuf, tmplen);
*p += tmplen;
@ -158,8 +175,8 @@ bool rsa_write_pem_public_key(rsa_t *rsa, FILE *fp) {
uint8_t derbuf2[8096];
uint8_t *derp1 = derbuf1;
uint8_t *derp2 = derbuf2;
size_t derlen1 = sizeof derbuf1;
size_t derlen2 = sizeof derbuf2;
size_t derlen1 = sizeof(derbuf1);
size_t derlen2 = sizeof(derbuf2);
if(!ber_write_mpi(&derp1, &derlen1, &rsa->n)
|| !ber_write_mpi(&derp1, &derlen1, &rsa->e)
@ -181,8 +198,8 @@ bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp) {
uint8_t derbuf2[8096];
uint8_t *derp1 = derbuf1;
uint8_t *derp2 = derbuf2;
size_t derlen1 = sizeof derbuf1;
size_t derlen2 = sizeof derbuf2;
size_t derlen1 = sizeof(derbuf1);
size_t derlen2 = sizeof(derbuf2);
if(!ber_write_mpi(&derp1, &derlen1, &bits)
|| ber_write_mpi(&derp1, &derlen1, &rsa->n) // modulus
@ -192,8 +209,10 @@ bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp) {
|| ber_write_mpi(&derp1, &derlen1, &q)
|| ber_write_mpi(&derp1, &derlen1, &exp1)
|| ber_write_mpi(&derp1, &derlen1, &exp2)
|| ber_write_mpi(&derp1, &derlen1, &coeff))
|| ber_write_mpi(&derp1, &derlen1, &coeff)) {
logger(DEBUG_ALWAYS, LOG_ERR, "Error while encoding RSA private key");
}
return false;
}

View file

@ -183,8 +183,7 @@ int optopt = '?';
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
`--' can cause `getopt' to return -1 with `optind' != ARGC. */
static enum
{
static enum {
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
} ordering;
@ -210,12 +209,14 @@ my_index (str, chr)
const char *str;
int chr;
{
while (*str)
{
if (*str == chr)
while(*str) {
if(*str == chr) {
return (char *) str;
}
str++;
}
return 0;
}
@ -262,8 +263,7 @@ extern pid_t __libc_pid;
to getopt is that one passed to the process. */
static void
__attribute__((__unused__))
store_args_and_env (int argc, char *const *argv)
{
store_args_and_env(int argc, char *const *argv) {
/* XXX This is no good solution. We should rather copy the args so
that we can compare them later. But we must not use malloc(3). */
original_argc = argc;
@ -310,18 +310,18 @@ exchange (argv)
but it consists of two parts that need to be swapped next. */
#ifdef _LIBC
/* First make sure the handling of the `__getopt_nonoption_flags'
string can work normally. Our top argument must be in the range
of the string. */
if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
{
if(nonoption_flags_len > 0 && top >= nonoption_flags_max_len) {
/* We must extend the array. The user plays games with us and
presents new arguments. */
char *new_str = malloc(top + 1);
if (new_str == NULL)
if(new_str == NULL) {
nonoption_flags_len = nonoption_flags_max_len = 0;
else
{
} else {
memcpy(new_str, __getopt_nonoption_flags, nonoption_flags_max_len);
memset(&new_str[nonoption_flags_max_len], '\0',
top + 1 - nonoption_flags_max_len);
@ -329,41 +329,38 @@ exchange (argv)
__getopt_nonoption_flags = new_str;
}
}
#endif
while (top > middle && middle > bottom)
{
if (top - middle > middle - bottom)
{
while(top > middle && middle > bottom) {
if(top - middle > middle - bottom) {
/* Bottom segment is the short one. */
int len = middle - bottom;
register int i;
/* Swap it with the top part of the top segment. */
for (i = 0; i < len; i++)
{
for(i = 0; i < len; i++) {
tem = argv[bottom + i];
argv[bottom + i] = argv[top - (middle - bottom) + i];
argv[top - (middle - bottom) + i] = tem;
SWAP_FLAGS(bottom + i, top - (middle - bottom) + i);
}
/* Exclude the moved bottom segment from further swapping. */
top -= len;
}
else
{
} else {
/* Top segment is the short one. */
int len = top - middle;
register int i;
/* Swap it with the bottom part of the bottom segment. */
for (i = 0; i < len; i++)
{
for(i = 0; i < len; i++) {
tem = argv[bottom + i];
argv[bottom + i] = argv[middle + i];
argv[middle + i] = tem;
SWAP_FLAGS(bottom + i, middle + i);
}
/* Exclude the moved top segment from further swapping. */
bottom += len;
}
@ -398,52 +395,52 @@ _getopt_initialize (argc, argv, optstring)
/* Determine how to handle the ordering of options and nonoptions. */
if (optstring[0] == '-')
{
if(optstring[0] == '-') {
ordering = RETURN_IN_ORDER;
++optstring;
}
else if (optstring[0] == '+')
{
} else if(optstring[0] == '+') {
ordering = REQUIRE_ORDER;
++optstring;
}
else if (posixly_correct != NULL)
} else if(posixly_correct != NULL) {
ordering = REQUIRE_ORDER;
else
} else {
ordering = PERMUTE;
}
#ifdef _LIBC
if(posixly_correct == NULL
&& argc == original_argc && argv == original_argv)
{
if (nonoption_flags_max_len == 0)
{
&& argc == original_argc && argv == original_argv) {
if(nonoption_flags_max_len == 0) {
if(__getopt_nonoption_flags == NULL
|| __getopt_nonoption_flags[0] == '\0')
|| __getopt_nonoption_flags[0] == '\0') {
nonoption_flags_max_len = -1;
else
{
} else {
const char *orig_str = __getopt_nonoption_flags;
int len = nonoption_flags_max_len = strlen(orig_str);
if (nonoption_flags_max_len < argc)
if(nonoption_flags_max_len < argc) {
nonoption_flags_max_len = argc;
}
__getopt_nonoption_flags =
(char *) malloc(nonoption_flags_max_len);
if (__getopt_nonoption_flags == NULL)
if(__getopt_nonoption_flags == NULL) {
nonoption_flags_max_len = -1;
else
{
} else {
memcpy(__getopt_nonoption_flags, orig_str, len);
memset(&__getopt_nonoption_flags[len], '\0',
nonoption_flags_max_len - len);
}
}
}
nonoption_flags_len = nonoption_flags_max_len;
}
else
} else {
nonoption_flags_len = 0;
}
#endif
return optstring;
@ -516,10 +513,11 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
{
optarg = NULL;
if (optind == 0 || !__getopt_initialized)
{
if (optind == 0)
if(optind == 0 || !__getopt_initialized) {
if(optind == 0) {
optind = 1; /* Don't scan ARGV[0], the program name. */
}
optstring = _getopt_initialize(argc, argv, optstring);
__getopt_initialized = 1;
}
@ -536,32 +534,36 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
#endif
if (nextchar == NULL || *nextchar == '\0')
{
if(nextchar == NULL || *nextchar == '\0') {
/* Advance to the next ARGV-element. */
/* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
moved back by the user (who may also have changed the arguments). */
if (last_nonopt > optind)
if(last_nonopt > optind) {
last_nonopt = optind;
if (first_nonopt > optind)
first_nonopt = optind;
}
if (ordering == PERMUTE)
{
if(first_nonopt > optind) {
first_nonopt = optind;
}
if(ordering == PERMUTE) {
/* If we have just processed some options following some non-options,
exchange them so that the options come first. */
if (first_nonopt != last_nonopt && last_nonopt != optind)
if(first_nonopt != last_nonopt && last_nonopt != optind) {
exchange((char **) argv);
else if (last_nonopt != optind)
} else if(last_nonopt != optind) {
first_nonopt = optind;
}
/* Skip any additional non-options
and extend the range of non-options previously skipped. */
while (optind < argc && NONOPTION_P)
while(optind < argc && NONOPTION_P) {
optind++;
}
last_nonopt = optind;
}
@ -570,14 +572,15 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
then exchange with previous non-options as if it were an option,
then skip everything else like a non-option. */
if (optind != argc && !strcmp (argv[optind], "--"))
{
if(optind != argc && !strcmp(argv[optind], "--")) {
optind++;
if (first_nonopt != last_nonopt && last_nonopt != optind)
if(first_nonopt != last_nonopt && last_nonopt != optind) {
exchange((char **) argv);
else if (first_nonopt == last_nonopt)
} else if(first_nonopt == last_nonopt) {
first_nonopt = optind;
}
last_nonopt = argc;
optind = argc;
@ -586,22 +589,24 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
/* If we have done all the ARGV-elements, stop the scan
and back over any non-options that we skipped and permuted. */
if (optind == argc)
{
if(optind == argc) {
/* Set the next-arg-index to point at the non-options
that we previously skipped, so the caller will digest them. */
if (first_nonopt != last_nonopt)
if(first_nonopt != last_nonopt) {
optind = first_nonopt;
}
return -1;
}
/* If we have come to a non-option and did not permute it,
either stop the scan or describe it to the caller and pass it by. */
if (NONOPTION_P)
{
if (ordering == REQUIRE_ORDER)
if(NONOPTION_P) {
if(ordering == REQUIRE_ORDER) {
return -1;
}
optarg = argv[optind++];
return 1;
}
@ -630,8 +635,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
if(longopts != NULL
&& (argv[optind][1] == '-'
|| (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
{
|| (long_only && (argv[optind][2] || !my_index(optstring, argv[optind][1]))))) {
char *nameend;
const struct option *p;
const struct option *pfound = NULL;
@ -646,53 +650,47 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
/* Test all long options for either exact match
or abbreviated matches. */
for(p = longopts, option_index = 0; p->name; p++, option_index++)
if (!strncmp (p->name, nextchar, nameend - nextchar))
{
if(!strncmp(p->name, nextchar, nameend - nextchar)) {
if((unsigned int)(nameend - nextchar)
== (unsigned int) strlen (p->name))
{
== (unsigned int) strlen(p->name)) {
/* Exact match found. */
pfound = p;
indfound = option_index;
exact = 1;
break;
}
else if (pfound == NULL)
{
} else if(pfound == NULL) {
/* First nonexact match found. */
pfound = p;
indfound = option_index;
}
else
} else
/* Second or later nonexact match found. */
{
ambig = 1;
}
}
if (ambig && !exact)
{
if(ambig && !exact) {
if(opterr)
fprintf(stderr, "%s: option `%s' is ambiguous\n",
argv[0], argv[optind]);
nextchar += strlen(nextchar);
optind++;
optopt = 0;
return '?';
}
if (pfound != NULL)
{
if(pfound != NULL) {
option_index = indfound;
optind++;
if (*nameend)
{
if(*nameend) {
/* Don't test has_arg with >, because some C compilers don't
allow it to be used on enums. */
if (pfound->has_arg)
if(pfound->has_arg) {
optarg = nameend + 1;
else
{
if (opterr)
{
} else {
if(opterr) {
if(argv[optind - 1][1] == '-')
/* --option */
fprintf(stderr,
@ -710,30 +708,32 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
optopt = pfound->val;
return '?';
}
}
else if (pfound->has_arg == 1)
{
if (optind < argc)
} else if(pfound->has_arg == 1) {
if(optind < argc) {
optarg = argv[optind++];
else
{
} else {
if(opterr)
fprintf(stderr,
"%s: option `%s' requires an argument\n",
argv[0], argv[optind - 1]);
nextchar += strlen(nextchar);
optopt = pfound->val;
return optstring[0] == ':' ? ':' : '?';
}
}
nextchar += strlen(nextchar);
if (longind != NULL)
if(longind != NULL) {
*longind = option_index;
if (pfound->flag)
{
}
if(pfound->flag) {
*(pfound->flag) = pfound->val;
return 0;
}
return pfound->val;
}
@ -742,10 +742,8 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
option, then it's an error.
Otherwise interpret it as a short option. */
if(!long_only || argv[optind][1] == '-'
|| my_index (optstring, *nextchar) == NULL)
{
if (opterr)
{
|| my_index(optstring, *nextchar) == NULL) {
if(opterr) {
if(argv[optind][1] == '-')
/* --option */
fprintf(stderr, "%s: unrecognized option `--%s'\n",
@ -755,6 +753,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
fprintf(stderr, "%s: unrecognized option `%c%s'\n",
argv[0], argv[optind][0], nextchar);
}
nextchar = (char *) "";
optind++;
optopt = 0;
@ -769,13 +768,12 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
char *temp = my_index(optstring, c);
/* Increment `optind' when we start to process its last character. */
if (*nextchar == '\0')
if(*nextchar == '\0') {
++optind;
}
if (temp == NULL || c == ':')
{
if (opterr)
{
if(temp == NULL || c == ':') {
if(opterr) {
if(posixly_correct)
/* 1003.2 specifies the format of this message. */
fprintf(stderr, "%s: illegal option -- %c\n",
@ -784,12 +782,13 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
fprintf(stderr, "%s: invalid option -- %c\n",
argv[0], c);
}
optopt = c;
return '?';
}
/* Convenience. Treat POSIX -W foo same as long option --foo */
if (temp[0] == 'W' && temp[1] == ';')
{
if(temp[0] == 'W' && temp[1] == ';') {
char *nameend;
const struct option *p;
const struct option *pfound = NULL;
@ -799,32 +798,33 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
int option_index;
/* This is an option that requires an argument. */
if (*nextchar != '\0')
{
if(*nextchar != '\0') {
optarg = nextchar;
/* If we end this ARGV-element by taking the rest as an arg,
we must advance to the next element now. */
optind++;
}
else if (optind == argc)
{
if (opterr)
{
} else if(optind == argc) {
if(opterr) {
/* 1003.2 specifies the format of this message. */
fprintf(stderr, "%s: option requires an argument -- %c\n",
argv[0], c);
}
optopt = c;
if (optstring[0] == ':')
if(optstring[0] == ':') {
c = ':';
else
} else {
c = '?';
return c;
}
else
return c;
} else
/* We already incremented `optind' once;
increment it again when taking next ARGV-elt as argument. */
{
optarg = argv[optind++];
}
/* optarg is now the argument, see if it's in the
table of longopts. */
@ -835,46 +835,43 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
/* Test all long options for either exact match
or abbreviated matches. */
for(p = longopts, option_index = 0; p->name; p++, option_index++)
if (!strncmp (p->name, nextchar, nameend - nextchar))
{
if ((unsigned int) (nameend - nextchar) == strlen (p->name))
{
if(!strncmp(p->name, nextchar, nameend - nextchar)) {
if((unsigned int)(nameend - nextchar) == strlen(p->name)) {
/* Exact match found. */
pfound = p;
indfound = option_index;
exact = 1;
break;
}
else if (pfound == NULL)
{
} else if(pfound == NULL) {
/* First nonexact match found. */
pfound = p;
indfound = option_index;
}
else
} else
/* Second or later nonexact match found. */
{
ambig = 1;
}
if (ambig && !exact)
{
}
if(ambig && !exact) {
if(opterr)
fprintf(stderr, "%s: option `-W %s' is ambiguous\n",
argv[0], argv[optind]);
nextchar += strlen(nextchar);
optind++;
return '?';
}
if (pfound != NULL)
{
if(pfound != NULL) {
option_index = indfound;
if (*nameend)
{
if(*nameend) {
/* Don't test has_arg with >, because some C compilers don't
allow it to be used on enums. */
if (pfound->has_arg)
if(pfound->has_arg) {
optarg = nameend + 1;
else
{
} else {
if(opterr)
fprintf(stderr,
"%s: option `-W %s' doesn't allow an argument\n",
@ -883,80 +880,82 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
nextchar += strlen(nextchar);
return '?';
}
}
else if (pfound->has_arg == 1)
{
if (optind < argc)
} else if(pfound->has_arg == 1) {
if(optind < argc) {
optarg = argv[optind++];
else
{
} else {
if(opterr)
fprintf(stderr,
"%s: option `%s' requires an argument\n",
argv[0], argv[optind - 1]);
nextchar += strlen(nextchar);
return optstring[0] == ':' ? ':' : '?';
}
}
nextchar += strlen(nextchar);
if (longind != NULL)
if(longind != NULL) {
*longind = option_index;
if (pfound->flag)
{
}
if(pfound->flag) {
*(pfound->flag) = pfound->val;
return 0;
}
return pfound->val;
}
nextchar = NULL;
return 'W'; /* Let the application handle it. */
}
if (temp[1] == ':')
{
if (temp[2] == ':')
{
if(temp[1] == ':') {
if(temp[2] == ':') {
/* This is an option that accepts an argument optionally. */
if (*nextchar != '\0')
{
if(*nextchar != '\0') {
optarg = nextchar;
optind++;
}
else
} else {
optarg = NULL;
nextchar = NULL;
}
else
{
nextchar = NULL;
} else {
/* This is an option that requires an argument. */
if (*nextchar != '\0')
{
if(*nextchar != '\0') {
optarg = nextchar;
/* If we end this ARGV-element by taking the rest as an arg,
we must advance to the next element now. */
optind++;
}
else if (optind == argc)
{
if (opterr)
{
} else if(optind == argc) {
if(opterr) {
/* 1003.2 specifies the format of this message. */
fprintf(stderr,
"%s: option requires an argument -- %c\n",
argv[0], c);
}
optopt = c;
if (optstring[0] == ':')
if(optstring[0] == ':') {
c = ':';
else
} else {
c = '?';
}
else
} else
/* We already incremented `optind' once;
increment it again when taking next ARGV-elt as argument. */
{
optarg = argv[optind++];
}
nextchar = NULL;
}
}
return c;
}
}
@ -988,16 +987,16 @@ main (argc, argv)
int c;
int digit_optind = 0;
while (1)
{
while(1) {
int this_option_optind = optind ? optind : 1;
c = getopt(argc, argv, "abc:d:0123456789");
if (c == -1)
break;
switch (c)
{
if(c == -1) {
break;
}
switch(c) {
case '0':
case '1':
case '2':
@ -1008,8 +1007,10 @@ main (argc, argv)
case '7':
case '8':
case '9':
if (digit_optind != 0 && digit_optind != this_option_optind)
if(digit_optind != 0 && digit_optind != this_option_optind) {
printf("digits occur in two different argv-elements.\n");
}
digit_optind = this_option_optind;
printf("option %c\n", c);
break;
@ -1034,11 +1035,13 @@ main (argc, argv)
}
}
if (optind < argc)
{
if(optind < argc) {
printf("non-option ARGV-elements: ");
while (optind < argc)
while(optind < argc) {
printf("%s ", argv[optind++]);
}
printf("\n");
}

View file

@ -1,3 +1,6 @@
#ifndef TINC_GETOPT_H
#define TINC_GETOPT_H
/* Declarations for getopt.
Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc.
@ -78,8 +81,7 @@ extern int optopt;
one). For long options that have a zero `flag' field, `getopt'
returns the contents of the `val' field. */
struct option
{
struct option {
#if defined (__STDC__) && __STDC__
const char *name;
#else
@ -130,4 +132,4 @@ extern int _getopt_internal ();
}
#endif
#endif /* _GETOPT_H */
#endif

View file

@ -106,12 +106,10 @@ main (argc, argv)
int c;
int digit_optind = 0;
while (1)
{
while(1) {
int this_option_optind = optind ? optind : 1;
int option_index = 0;
static struct option long_options[] =
{
static struct option long_options[] = {
{"add", 1, 0, 0},
{"append", 0, 0, 0},
{"delete", 1, 0, 0},
@ -123,15 +121,19 @@ main (argc, argv)
c = getopt_long(argc, argv, "abc:d:0123456789",
long_options, &option_index);
if (c == -1)
break;
switch (c)
{
if(c == -1) {
break;
}
switch(c) {
case 0:
printf("option %s", long_options[option_index].name);
if (optarg)
if(optarg) {
printf(" with arg %s", optarg);
}
printf("\n");
break;
@ -145,8 +147,10 @@ main (argc, argv)
case '7':
case '8':
case '9':
if (digit_optind != 0 && digit_optind != this_option_optind)
if(digit_optind != 0 && digit_optind != this_option_optind) {
printf("digits occur in two different argv-elements.\n");
}
digit_optind = this_option_optind;
printf("option %c\n", c);
break;
@ -175,11 +179,13 @@ main (argc, argv)
}
}
if (optind < argc)
{
if(optind < argc) {
printf("non-option ARGV-elements: ");
while (optind < argc)
while(optind < argc) {
printf("%s ", argv[optind++]);
}
printf("\n");
}

View file

@ -68,15 +68,17 @@
static void mst_kruskal(void) {
/* Clear MST status on connections */
for list_each(connection_t, c, connection_list)
for list_each(connection_t, c, connection_list) {
c->status.mst = false;
}
logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Running Kruskal's algorithm:");
/* Clear visited status on nodes */
for splay_each(node_t, n, node_tree)
for splay_each(node_t, n, node_tree) {
n->status.visited = false;
}
/* Starting point */
@ -100,11 +102,13 @@ static void mst_kruskal(void) {
e->from->status.visited = true;
e->to->status.visited = true;
if(e->connection)
if(e->connection) {
e->connection->status.mst = true;
}
if(e->reverse->connection)
if(e->reverse->connection) {
e->reverse->connection->status.mst = true;
}
logger(DEBUG_SCARY_THINGS, LOG_DEBUG, " Adding edge %s - %s weight %d", e->from->name, e->to->name, e->weight);
@ -145,12 +149,14 @@ static void sssp_bfs(void) {
for list_each(node_t, n, todo_list) { /* "n" is the node from which we start */
logger(DEBUG_SCARY_THINGS, LOG_DEBUG, " Examining edges from %s", n->name);
if(n->distance < 0)
if(n->distance < 0) {
abort();
}
for splay_each(edge_t, e, n->edge_tree) { /* "e" is the edge connected to "from" */
if(!e->reverse || e->to == myself)
if(!e->reverse || e->to == myself) {
continue;
}
/* Situation:
@ -173,13 +179,15 @@ static void sssp_bfs(void) {
if(e->to->status.visited
&& (!e->to->status.indirect || indirect)
&& (e->to->distance != n->distance + 1 || e->weight >= e->to->prevedge->weight))
&& (e->to->distance != n->distance + 1 || e->weight >= e->to->prevedge->weight)) {
continue;
}
// Only update nexthop if it doesn't increase the path length
if(!e->to->status.visited || (e->to->distance == n->distance + 1 && e->weight >= e->to->prevedge->weight))
if(!e->to->status.visited || (e->to->distance == n->distance + 1 && e->weight >= e->to->prevedge->weight)) {
e->to->nexthop = (n->nexthop == myself) ? e->to : n->nexthop;
}
e->to->status.visited = true;
e->to->status.indirect = indirect;
@ -188,8 +196,9 @@ static void sssp_bfs(void) {
e->to->options = e->options;
e->to->distance = n->distance + 1;
if(!e->to->status.reachable || (e->to->address.sa.sa_family == AF_UNSPEC && e->address.sa.sa_family != AF_UNKNOWN))
if(!e->to->status.reachable || (e->to->address.sa.sa_family == AF_UNSPEC && e->address.sa.sa_family != AF_UNKNOWN)) {
update_node_udp(e->to, &e->address);
}
list_insert_tail(todo_list, e->to);
}
@ -207,6 +216,7 @@ static void check_reachability(void) {
int reachable_count = 0;
int became_reachable_count = 0;
int became_unreachable_count = 0;
for splay_each(node_t, n, node_tree) {
if(n->status.visited != n->status.reachable) {
n->status.reachable = !n->status.reachable;
@ -215,25 +225,32 @@ static void check_reachability(void) {
if(n->status.reachable) {
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Node %s (%s) became reachable",
n->name, n->hostname);
if (n != myself)
if(n != myself) {
became_reachable_count++;
}
} else {
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Node %s (%s) became unreachable",
n->name, n->hostname);
if (n != myself)
if(n != myself) {
became_unreachable_count++;
}
}
if(experimental && OPTION_VERSION(n->options) >= 2)
if(experimental && OPTION_VERSION(n->options) >= 2) {
n->status.sptps = true;
}
/* TODO: only clear status.validkey if node is unreachable? */
n->status.validkey = false;
if(n->status.sptps) {
sptps_stop(&n->sptps);
n->status.waitingforkey = false;
}
n->last_req_key = 0;
n->status.udp_confirmed = false;
@ -269,26 +286,29 @@ static void check_reachability(void) {
if(!n->status.reachable) {
update_node_udp(n, NULL);
memset(&n->status, 0, sizeof n->status);
memset(&n->status, 0, sizeof(n->status));
n->options = 0;
} else if(n->connection) {
// Speed up UDP probing by sending our key.
if(!n->status.sptps)
if(!n->status.sptps) {
send_ans_key(n);
}
}
}
if(n->status.reachable && n != myself)
if(n->status.reachable && n != myself) {
reachable_count++;
}
}
if(device_standby) {
if (reachable_count == 0 && became_unreachable_count > 0)
if(reachable_count == 0 && became_unreachable_count > 0) {
device_disable();
else if (reachable_count > 0 && reachable_count == became_reachable_count)
} else if(reachable_count > 0 && reachable_count == became_reachable_count) {
device_enable();
}
}
}
void graph(void) {
subnet_cache_flush();

View file

@ -1,3 +1,6 @@
#ifndef TINC_GRAPH_H
#define TINC_GRAPH_H
/*
graph.h -- header for graph.c
Copyright (C) 2001-2012 Guus Sliepen <guus@tinc-vpn.org>,
@ -18,10 +21,7 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __TINC_GRAPH_H__
#define __TINC_GRAPH_H__
extern void graph(void);
extern void dump_graph(void);
#endif /* __TINC_GRAPH_H__ */
#endif

View file

@ -27,36 +27,44 @@
static uint32_t hash_function(const void *p, size_t len) {
const uint8_t *q = p;
uint32_t hash = 0;
while(true) {
for(int i = len > 4 ? 4 : len; --i;)
for(int i = len > 4 ? 4 : len; --i;) {
hash += (uint32_t)q[len - i] << (8 * i);
}
hash *= 0x9e370001UL; // Golden ratio prime.
if(len <= 4)
if(len <= 4) {
break;
}
len -= 4;
}
return hash;
}
/* Map 32 bits int onto 0..n-1, without throwing away too many bits if n is 2^8 or 2^16 */
static uint32_t modulo(uint32_t hash, size_t n) {
if(n == 0x100)
if(n == 0x100) {
return (hash >> 24) ^ ((hash >> 16) & 0xff) ^ ((hash >> 8) & 0xff) ^ (hash & 0xff);
else if(n == 0x10000)
} else if(n == 0x10000) {
return (hash >> 16) ^ (hash & 0xffff);
else
} else {
return hash % n;
}
}
/* (De)allocation */
hash_t *hash_alloc(size_t n, size_t size) {
hash_t *hash = xzalloc(sizeof *hash);
hash_t *hash = xzalloc(sizeof(*hash));
hash->n = n;
hash->size = size;
hash->keys = xzalloc(hash->n * hash->size);
hash->values = xzalloc(hash->n * sizeof *hash->values);
hash->values = xzalloc(hash->n * sizeof(*hash->values));
return hash;
}
@ -76,16 +84,21 @@ void hash_insert(hash_t *hash, const void *key, const void *value) {
void *hash_search(const hash_t *hash, const void *key) {
uint32_t i = modulo(hash_function(key, hash->size), hash->n);
if(hash->values[i] && !memcmp(key, hash->keys + i * hash->size, hash->size)) {
return (void *)hash->values[i];
}
return NULL;
}
void *hash_search_or_insert(hash_t *hash, const void *key, const void *value) {
uint32_t i = modulo(hash_function(key, hash->size), hash->n);
if(hash->values[i] && !memcmp(key, hash->keys + i * hash->size, hash->size))
if(hash->values[i] && !memcmp(key, hash->keys + i * hash->size, hash->size)) {
return (void *)hash->values[i];
}
memcpy(hash->keys + i * hash->size, key, hash->size);
hash->values[i] = value;
return NULL;
@ -101,14 +114,15 @@ void hash_delete(hash_t *hash, const void *key) {
/* Utility functions */
void hash_clear(hash_t *hash) {
memset(hash->values, 0, hash->n * sizeof *hash->values);
memset(hash->values, 0, hash->n * sizeof(*hash->values));
}
void hash_resize(hash_t *hash, size_t n) {
hash->keys = xrealloc(hash->keys, n * hash->size);
hash->values = xrealloc(hash->values, n * sizeof *hash->values);
hash->values = xrealloc(hash->values, n * sizeof(*hash->values));
if(n > hash->n) {
memset(hash->keys + hash->n * hash->size, 0, (n - hash->n) * hash->size);
memset(hash->values + hash->n, 0, (n - hash->n) * sizeof *hash->values);
memset(hash->values + hash->n, 0, (n - hash->n) * sizeof(*hash->values));
}
}

View file

@ -1,3 +1,6 @@
#ifndef TINC_HASH_H
#define TINC_HASH_H
/*
hash.h -- header file for hash.c
Copyright (C) 2012 Guus Sliepen <guus@tinc-vpn.org>
@ -17,9 +20,6 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __TINC_HASH_H__
#define __TINC_HASH_H__
typedef struct hash_t {
size_t n;
size_t size;
@ -39,4 +39,4 @@ extern void *hash_search_or_insert(hash_t *, const void *key, const void *value)
extern void hash_clear(hash_t *);
extern void hash_resize(hash_t *, size_t n);
#endif /* __TINC_HASH_H__ */
#endif

Some files were not shown because too many files have changed in this diff Show more