Import Upstream version 1.1~pre17
This commit is contained in:
parent
bc8ca65653
commit
b511a112e6
216 changed files with 43313 additions and 18448 deletions
2
COPYING
2
COPYING
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
|
34
Makefile.in
34
Makefile.in
|
@ -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:
|
||||
|
|
40
NEWS
40
NEWS
|
@ -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.
|
||||
|
||||
|
@ -552,7 +584,7 @@ Thanks to Scott Lamb for his contributions to this version of tinc.
|
|||
* Tinc will retry to connect upon startup, does not quit if it doesn't
|
||||
work the first time.
|
||||
* Hosts that are disconnected implicitly if we lose a connection get
|
||||
deleted from the internal list, to prevent hogging eachother with
|
||||
deleted from the internal list, to prevent hogging each other with
|
||||
add and delete requests when the connection is restored.
|
||||
|
||||
# Version 1.0pre1 May 12 2000
|
||||
|
|
30
README
30
README
|
@ -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.
|
||||
|
||||
|
@ -82,7 +96,7 @@ Ethernet network switch or hub.
|
|||
|
||||
Normally, when started tinc will detach and run in the background. In a native
|
||||
Windows environment this means tinc will install itself as a service, which will
|
||||
restart after reboots. To prevent tinc from detaching or running as a service,
|
||||
restart after reboots. To prevent tinc from detaching or running as a service,
|
||||
use the -D option.
|
||||
|
||||
The status of the VPN can be queried using the "tinc" command, which connects
|
||||
|
|
18
THANKS
18
THANKS
|
@ -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
|
||||
|
|
190
aclocal.m4
vendored
190
aclocal.m4
vendored
|
@ -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
|
||||
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
|
||||
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
|
||||
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
|
||||
fi
|
||||
AC_SUBST([am__include])
|
||||
AC_SUBST([am__quote])
|
||||
AC_MSG_RESULT([$_am_result])
|
||||
rm -f confinc confmf
|
||||
])
|
||||
# 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
|
||||
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
13
compile
|
@ -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:
|
||||
|
|
584
config.guess
vendored
584
config.guess
vendored
File diff suppressed because it is too large
Load diff
19
config.h.in
19
config.h.in
|
@ -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__
|
||||
|
|
258
config.sub
vendored
258
config.sub
vendored
|
@ -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
|
||||
|
@ -903,7 +895,7 @@ case $basic_machine in
|
|||
basic_machine=v70-nec
|
||||
os=-sysv
|
||||
;;
|
||||
next | m*-next )
|
||||
next | m*-next)
|
||||
basic_machine=m68k-next
|
||||
case $os in
|
||||
-nextstep* )
|
||||
|
@ -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
|
||||
;;
|
||||
|
@ -1484,7 +1459,7 @@ case $os in
|
|||
-nova*)
|
||||
os=-rtmk-nova
|
||||
;;
|
||||
-ns2 )
|
||||
-ns2)
|
||||
os=-nextstep2
|
||||
;;
|
||||
-nsk*)
|
||||
|
@ -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
|
||||
;;
|
||||
|
@ -1683,7 +1662,7 @@ case $basic_machine in
|
|||
m88k-omron*)
|
||||
os=-luna
|
||||
;;
|
||||
*-next )
|
||||
*-next)
|
||||
os=-nextstep
|
||||
;;
|
||||
*-sequent)
|
||||
|
@ -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: "'"
|
||||
|
|
21
configure.ac
21
configure.ac
|
@ -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
|
||||
|
|
8
depcomp
8
depcomp
|
@ -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"
|
||||
|
|
|
@ -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 > $@
|
||||
|
|
|
@ -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.
15
doc/sample-config/hosts/alpha
Normal file
15
doc/sample-config/hosts/alpha
Normal 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-----
|
16
doc/sample-config/hosts/beta
Normal file
16
doc/sample-config/hosts/beta
Normal 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-----
|
1
doc/sample-config/rsa_key.priv
Normal file
1
doc/sample-config/rsa_key.priv
Normal file
|
@ -0,0 +1 @@
|
|||
# Generate this file with `tincd -n example -K`
|
4
doc/sample-config/tinc-down
Normal file
4
doc/sample-config/tinc-down
Normal 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
11
doc/sample-config/tinc-up
Normal 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
|
22
doc/sample-config/tinc.conf
Normal file
22
doc/sample-config/tinc.conf
Normal 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
|
5266
doc/texinfo.tex
5266
doc/texinfo.tex
File diff suppressed because it is too large
Load diff
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 ,
|
||||
|
|
518
doc/tinc.info
518
doc/tinc.info
|
@ -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
|
||||
|
@ -119,7 +119,7 @@ both the receiving and sending end, it has become largely
|
|||
runtime-configurable--in short, it has become a full-fledged
|
||||
professional package.
|
||||
|
||||
Tinc also allows more than two sites to connect to eachother and form a
|
||||
Tinc also allows more than two sites to connect to each other and form a
|
||||
single VPN. Traditionally VPNs are created by making tunnels, which only
|
||||
have two endpoints. Larger VPNs with more sites are created by adding
|
||||
more tunnels. Tinc takes another approach: only endpoints are
|
||||
|
@ -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,16 +961,24 @@ 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)
|
||||
should be resolved. Since DNS lookups are blocking, it might
|
||||
affect tinc's efficiency, even stopping the daemon for a few
|
||||
seconds everytime it does a lookup if your DNS server is not
|
||||
seconds every time it does a lookup if your DNS server is not
|
||||
responding.
|
||||
|
||||
This does not affect resolving hostnames to IP addresses from the
|
||||
|
@ -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
|
||||
|
|
242
doc/tinc.texi
242
doc/tinc.texi
|
@ -15,7 +15,7 @@
|
|||
|
||||
This is the info manual for @value{PACKAGE} version @value{VERSION}, a Virtual Private Network daemon.
|
||||
|
||||
Copyright @copyright{} 1998-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>.
|
||||
|
||||
|
@ -161,7 +161,7 @@ professional package.
|
|||
|
||||
@cindex traditional VPNs
|
||||
@cindex scalability
|
||||
Tinc also allows more than two sites to connect to eachother and form a single VPN.
|
||||
Tinc also allows more than two sites to connect to each other and form a single VPN.
|
||||
Traditionally VPNs are created by making tunnels, which only have two endpoints.
|
||||
Larger VPNs with more sites are created by adding more tunnels.
|
||||
Tinc takes another approach: only endpoints are specified,
|
||||
|
@ -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,16 +1041,24 @@ 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)
|
||||
should be resolved. Since DNS lookups are blocking, it might affect
|
||||
tinc's efficiency, even stopping the daemon for a few seconds everytime
|
||||
tinc's efficiency, even stopping the daemon for a few seconds every time
|
||||
it does a lookup if your DNS server is not responding.
|
||||
|
||||
This does not affect resolving hostnames to IP addresses from the
|
||||
|
@ -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
|
||||
|
|
|
@ -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
5
doc/tincinclude.texi
Normal file
|
@ -0,0 +1,5 @@
|
|||
@set VERSION 1.1pre17
|
||||
@set PACKAGE tinc
|
||||
@set sysconfdir /etc
|
||||
@set localstatedir /var
|
||||
@set runstatedir /var/run
|
|
@ -2,3 +2,4 @@
|
|||
@set PACKAGE @PACKAGE@
|
||||
@set sysconfdir @sysconfdir@
|
||||
@set localstatedir @localstatedir@
|
||||
@set runstatedir @runstatedir@
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
dist_bin_SCRIPTS = tinc-gui
|
||||
|
||||
extra_DIST = README.gui
|
507
gui/Makefile.in
507
gui/Makefile.in
|
@ -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:
|
634
gui/tinc-gui
634
gui/tinc-gui
|
@ -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)
|
36
install-sh
36
install-sh
|
@ -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
264
m4/ax_code_coverage.m4
Normal 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])])
|
||||
])
|
|
@ -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.")]
|
||||
|
|
|
@ -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
16
missing
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
516
src/Makefile.in
516
src/Makefile.in
|
@ -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
277
src/address_cache.c
Normal 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
50
src/address_cache.h
Normal 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
|
|
@ -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,9 +168,11 @@ 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. */
|
||||
|
@ -160,10 +180,11 @@ void do_autoconnect() {
|
|||
make_new_connection();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* 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. */
|
||||
|
|
|
@ -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
|
||||
|
|
422
src/bsd/device.c
422
src/bsd/device.c
|
@ -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,35 +128,43 @@ 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)
|
||||
device_type = DEVICE_TYPE_TAP;
|
||||
if((device && strstr(device, "tap")) || routing_mode != RMODE_ROUTER) {
|
||||
device_type = DEVICE_TYPE_TAP;
|
||||
}
|
||||
}
|
||||
|
||||
if(routing_mode == RMODE_SWITCH && device_type != DEVICE_TYPE_TAP) {
|
||||
|
@ -163,28 +175,32 @@ 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);
|
||||
}
|
||||
break;
|
||||
|
||||
case DEVICE_TYPE_TUNEMU: {
|
||||
char dynamic_name[256] = "";
|
||||
device_fd = tunemu_open(dynamic_name);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_NET_IF_UTUN_H
|
||||
case DEVICE_TYPE_UTUN:
|
||||
return setup_utun();
|
||||
|
||||
case DEVICE_TYPE_UTUN:
|
||||
return setup_utun();
|
||||
#endif
|
||||
default:
|
||||
device_fd = open(device, O_RDWR | O_NONBLOCK);
|
||||
|
||||
default:
|
||||
device_fd = open(device, O_RDWR | O_NONBLOCK);
|
||||
}
|
||||
|
||||
if(device_fd < 0) {
|
||||
|
@ -204,87 +220,105 @@ 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:
|
||||
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:
|
||||
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);
|
||||
const int mode = IFF_BROADCAST | IFF_MULTICAST;
|
||||
ioctl(device_fd, TUNSIFMODE, &mode, sizeof(mode));
|
||||
}
|
||||
#endif
|
||||
|
||||
device_info = "Generic BSD tun device";
|
||||
break;
|
||||
case DEVICE_TYPE_TAP:
|
||||
if(routing_mode == RMODE_ROUTER)
|
||||
overwrite_mac = true;
|
||||
device_info = "Generic BSD tap device";
|
||||
device_info = "Generic BSD tun device";
|
||||
break;
|
||||
|
||||
case DEVICE_TYPE_TAP:
|
||||
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);
|
||||
}
|
||||
{
|
||||
struct ifreq ifr;
|
||||
|
||||
if(ioctl(device_fd, TAPGIFNAME, (void *)&ifr) == 0) {
|
||||
free(iface);
|
||||
iface = xstrdup(ifr.ifr_name);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
break;
|
||||
break;
|
||||
#ifdef ENABLE_TUNEMU
|
||||
case DEVICE_TYPE_TUNEMU:
|
||||
device_info = "BSD tunemu device";
|
||||
break;
|
||||
|
||||
case DEVICE_TYPE_TUNEMU:
|
||||
device_info = "BSD tunemu device";
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
#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;
|
||||
|
||||
case DEVICE_TYPE_TUNEMU:
|
||||
tunemu_close(device_fd);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
close(device_fd);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -313,154 +352,163 @@ static bool read_packet(vpn_packet_t *packet) {
|
|||
int inlen;
|
||||
|
||||
switch(device_type) {
|
||||
case DEVICE_TYPE_TUN:
|
||||
case DEVICE_TYPE_TUN:
|
||||
#ifdef ENABLE_TUNEMU
|
||||
case DEVICE_TYPE_TUNEMU:
|
||||
if(device_type == DEVICE_TYPE_TUNEMU)
|
||||
inlen = tunemu_read(device_fd, DATA(packet) + 14, MTU - 14);
|
||||
else
|
||||
case DEVICE_TYPE_TUNEMU:
|
||||
if(device_type == DEVICE_TYPE_TUNEMU) {
|
||||
inlen = tunemu_read(device_fd, DATA(packet) + 14, MTU - 14);
|
||||
} else
|
||||
#endif
|
||||
inlen = read(device_fd, DATA(packet) + 14, MTU - 14);
|
||||
inlen = read(device_fd, DATA(packet) + 14, MTU - 14);
|
||||
|
||||
if(inlen <= 0) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info,
|
||||
device, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
switch(DATA(packet)[14] >> 4) {
|
||||
case 4:
|
||||
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",
|
||||
DATA(packet)[14] >> 4, device_info, device);
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(DATA(packet), 0, 12);
|
||||
packet->len = inlen + 14;
|
||||
break;
|
||||
|
||||
case DEVICE_TYPE_UTUN:
|
||||
case DEVICE_TYPE_TUNIFHEAD: {
|
||||
if((inlen = read(device_fd, DATA(packet) + 10, MTU - 10)) <= 0) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info,
|
||||
device, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (DATA(packet)[14] >> 4) {
|
||||
case 4:
|
||||
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",
|
||||
DATA(packet)[14] >> 4, device_info, device);
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(DATA(packet), 0, 12);
|
||||
packet->len = inlen + 10;
|
||||
break;
|
||||
if(inlen <= 0) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info,
|
||||
device, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
case DEVICE_TYPE_TAP:
|
||||
if((inlen = read(device_fd, DATA(packet), MTU)) <= 0) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info,
|
||||
device, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
switch(DATA(packet)[14] >> 4) {
|
||||
case 4:
|
||||
DATA(packet)[12] = 0x08;
|
||||
DATA(packet)[13] = 0x00;
|
||||
break;
|
||||
|
||||
packet->len = inlen;
|
||||
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",
|
||||
DATA(packet)[14] >> 4, device_info, device);
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(DATA(packet), 0, 12);
|
||||
packet->len = inlen + 14;
|
||||
break;
|
||||
|
||||
case DEVICE_TYPE_UTUN:
|
||||
case DEVICE_TYPE_TUNIFHEAD: {
|
||||
if((inlen = read(device_fd, DATA(packet) + 10, MTU - 10)) <= 0) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info,
|
||||
device, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
switch(DATA(packet)[14] >> 4) {
|
||||
case 4:
|
||||
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",
|
||||
DATA(packet)[14] >> 4, device_info, device);
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(DATA(packet), 0, 12);
|
||||
packet->len = inlen + 10;
|
||||
break;
|
||||
}
|
||||
|
||||
case DEVICE_TYPE_TAP:
|
||||
if((inlen = read(device_fd, DATA(packet), MTU)) <= 0) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info,
|
||||
device, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
packet->len = inlen;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s",
|
||||
packet->len, device_info);
|
||||
packet->len, device_info);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool write_packet(vpn_packet_t *packet) {
|
||||
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s",
|
||||
packet->len, device_info);
|
||||
packet->len, device_info);
|
||||
|
||||
switch(device_type) {
|
||||
case DEVICE_TYPE_TUN:
|
||||
if(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;
|
||||
|
||||
case DEVICE_TYPE_UTUN:
|
||||
case DEVICE_TYPE_TUNIFHEAD: {
|
||||
int af = (DATA(packet)[12] << 8) + DATA(packet)[13];
|
||||
uint32_t type;
|
||||
|
||||
switch (af) {
|
||||
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",
|
||||
af, device_info, device);
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
case DEVICE_TYPE_TUN:
|
||||
if(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;
|
||||
}
|
||||
|
||||
case DEVICE_TYPE_TAP:
|
||||
if(write(device_fd, DATA(packet), packet->len) < 0) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info,
|
||||
device, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case DEVICE_TYPE_UTUN:
|
||||
case DEVICE_TYPE_TUNIFHEAD: {
|
||||
int af = (DATA(packet)[12] << 8) + DATA(packet)[13];
|
||||
uint32_t type;
|
||||
|
||||
switch(af) {
|
||||
case 0x0800:
|
||||
type = htonl(AF_INET);
|
||||
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;
|
||||
}
|
||||
case 0x86DD:
|
||||
type = htonl(AF_INET6);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
logger(DEBUG_TRAFFIC, LOG_ERR,
|
||||
"Unknown address family %x while writing packet to %s %s",
|
||||
af, device_info, device);
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
case DEVICE_TYPE_TAP:
|
||||
if(write(device_fd, DATA(packet), packet->len) < 0) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info,
|
||||
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
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
213
src/bsd/tunemu.c
213
src/bsd/tunemu.c
|
@ -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
|
||||
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()
|
||||
{
|
||||
int fd = getdtablesize();
|
||||
while (fd--)
|
||||
close(fd);
|
||||
static void closeall() {
|
||||
int fd = getdtablesize();
|
||||
|
||||
open("/dev/null", O_RDWR, 0);
|
||||
dup(0);
|
||||
dup(0);
|
||||
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,74 +137,73 @@ 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)
|
||||
int ppp_sockfd = socket(PF_PPP, SOCK_RAW, PPPPROTO_CTL);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// connect to ppp procotol
|
||||
struct sockaddr_ppp pppaddr;
|
||||
pppaddr.ppp_len = sizeof(struct sockaddr_ppp);
|
||||
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)
|
||||
{
|
||||
struct sockaddr_ppp pppaddr;
|
||||
pppaddr.ppp_len = sizeof(struct sockaddr_ppp);
|
||||
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) {
|
||||
tun_error("connecting ppp socket: %s", strerror(errno));
|
||||
close(ppp_sockfd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
tun_noerror();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
tun_noerror();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// allow packets
|
||||
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;
|
||||
}
|
||||
|
|
18
src/buffer.c
18
src/buffer.c
|
@ -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);
|
||||
}
|
||||
|
|
18
src/buffer.h
18
src/buffer.h
|
@ -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
|
||||
|
|
|
@ -11,42 +11,40 @@ 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;
|
||||
p[1] = (uint8_t) (v >> 48) & 0xff;
|
||||
p[2] = (uint8_t) (v >> 40) & 0xff;
|
||||
p[3] = (uint8_t) (v >> 32) & 0xff;
|
||||
p[4] = (uint8_t) (v >> 24) & 0xff;
|
||||
p[5] = (uint8_t) (v >> 16) & 0xff;
|
||||
p[6] = (uint8_t) (v >> 8) & 0xff;
|
||||
p[0] = (uint8_t)(v >> 56) & 0xff;
|
||||
p[1] = (uint8_t)(v >> 48) & 0xff;
|
||||
p[2] = (uint8_t)(v >> 40) & 0xff;
|
||||
p[3] = (uint8_t)(v >> 32) & 0xff;
|
||||
p[4] = (uint8_t)(v >> 24) & 0xff;
|
||||
p[5] = (uint8_t)(v >> 16) & 0xff;
|
||||
p[6] = (uint8_t)(v >> 8) & 0xff;
|
||||
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 */
|
||||
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 */
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
||||
if(kbits == 256) { /* recommended */
|
||||
k += 16;
|
||||
constants = sigma;
|
||||
} else { /* kbits == 128 */
|
||||
} 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];
|
||||
|
@ -108,14 +108,17 @@ chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes
|
|||
j14 = x->input[14];
|
||||
j15 = x->input[15];
|
||||
|
||||
for (;;) {
|
||||
if (bytes < 64) {
|
||||
for (i = 0; i < bytes; ++i)
|
||||
for(;;) {
|
||||
if(bytes < 64) {
|
||||
for(i = 0; i < bytes; ++i) {
|
||||
tmp[i] = m[i];
|
||||
}
|
||||
|
||||
m = tmp;
|
||||
ctarget = c;
|
||||
c = tmp;
|
||||
}
|
||||
|
||||
x0 = j0;
|
||||
x1 = j1;
|
||||
x2 = j2;
|
||||
|
@ -132,7 +135,8 @@ 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) {
|
||||
|
||||
for(i = 20; i > 0; i -= 2) {
|
||||
QUARTERROUND(x0, x4, x8, x12)
|
||||
QUARTERROUND(x1, x5, x9, x13)
|
||||
QUARTERROUND(x2, x6, x10, x14)
|
||||
|
@ -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,7 +182,8 @@ 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) {
|
||||
|
||||
if(!j12) {
|
||||
j13 = PLUSONE(j13);
|
||||
/* stopping at 2^70 bytes per nonce is user's responsibility */
|
||||
}
|
||||
|
@ -199,15 +205,18 @@ chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes
|
|||
U32TO8_LITTLE(c + 56, x14);
|
||||
U32TO8_LITTLE(c + 60, x15);
|
||||
|
||||
if (bytes <= 64) {
|
||||
if (bytes < 64) {
|
||||
for (i = 0; i < bytes; ++i)
|
||||
if(bytes <= 64) {
|
||||
if(bytes < 64) {
|
||||
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;
|
||||
|
|
|
@ -11,14 +11,14 @@ struct chacha_ctx {
|
|||
uint32_t input[16];
|
||||
};
|
||||
|
||||
#define CHACHA_MINKEYLEN 16
|
||||
#define CHACHA_NONCELEN 8
|
||||
#define CHACHA_CTRLEN 8
|
||||
#define CHACHA_STATELEN (CHACHA_NONCELEN+CHACHA_CTRLEN)
|
||||
#define CHACHA_BLOCKLEN 64
|
||||
#define CHACHA_MINKEYLEN 16
|
||||
#define CHACHA_NONCELEN 8
|
||||
#define CHACHA_CTRLEN 8
|
||||
#define CHACHA_STATELEN (CHACHA_NONCELEN+CHACHA_CTRLEN)
|
||||
#define CHACHA_BLOCKLEN 64
|
||||
|
||||
void chacha_keysetup(struct chacha_ctx *x, const uint8_t *k, uint32_t kbits);
|
||||
void chacha_ivsetup(struct chacha_ctx *x, const uint8_t *iv, const uint8_t *ctr);
|
||||
void chacha_encrypt_bytes(struct chacha_ctx *x, const uint8_t *m, uint8_t * c, uint32_t bytes);
|
||||
void chacha_encrypt_bytes(struct chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes);
|
||||
|
||||
#endif /* CHACHA_H */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Public Domain poly1305 from Andrew Moon
|
||||
* poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna
|
||||
*/
|
||||
|
@ -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,10 +70,11 @@ 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:
|
||||
poly1305_donna_16bytes:
|
||||
m += 16;
|
||||
inlen -= 16;
|
||||
|
||||
|
@ -89,7 +89,7 @@ poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t
|
|||
h3 += ((((uint64_t) t3 << 32) | t2) >> 14) & 0x3ffffff;
|
||||
h4 += (t3 >> 8) | (1 << 24);
|
||||
|
||||
poly1305_donna_mul:
|
||||
poly1305_donna_mul:
|
||||
t[0] = mul32x32_64(h0, r0) + mul32x32_64(h1, s4) + mul32x32_64(h2, s3) + mul32x32_64(h3, s2) + mul32x32_64(h4, s1);
|
||||
t[1] = mul32x32_64(h0, r1) + mul32x32_64(h1, r0) + mul32x32_64(h2, s4) + mul32x32_64(h3, s3) + mul32x32_64(h4, s2);
|
||||
t[2] = mul32x32_64(h0, r2) + mul32x32_64(h1, r1) + mul32x32_64(h2, r0) + mul32x32_64(h3, s4) + mul32x32_64(h4, s3);
|
||||
|
@ -100,31 +100,39 @@ poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t
|
|||
c = (t[0] >> 26);
|
||||
t[1] += c;
|
||||
h1 = (uint32_t) t[1] & 0x3ffffff;
|
||||
b = (uint32_t) (t[1] >> 26);
|
||||
b = (uint32_t)(t[1] >> 26);
|
||||
t[2] += b;
|
||||
h2 = (uint32_t) t[2] & 0x3ffffff;
|
||||
b = (uint32_t) (t[2] >> 26);
|
||||
b = (uint32_t)(t[2] >> 26);
|
||||
t[3] += b;
|
||||
h3 = (uint32_t) t[3] & 0x3ffffff;
|
||||
b = (uint32_t) (t[3] >> 26);
|
||||
b = (uint32_t)(t[3] >> 26);
|
||||
t[4] += b;
|
||||
h4 = (uint32_t) t[4] & 0x3ffffff;
|
||||
b = (uint32_t) (t[4] >> 26);
|
||||
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;
|
||||
poly1305_donna_atmost15bytes:
|
||||
|
||||
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);
|
||||
|
@ -140,7 +148,7 @@ poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t
|
|||
|
||||
goto poly1305_donna_mul;
|
||||
|
||||
poly1305_donna_finish:
|
||||
poly1305_donna_finish:
|
||||
b = h0 >> 26;
|
||||
h0 = h0 & 0x3ffffff;
|
||||
h1 += b;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* $OpenBSD: poly1305.h,v 1.2 2013/12/19 22:57:13 djm Exp $ */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Public Domain poly1305 from Andrew Moon
|
||||
* poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna
|
||||
*/
|
||||
|
@ -8,9 +8,9 @@
|
|||
#ifndef POLY1305_H
|
||||
#define POLY1305_H
|
||||
|
||||
#define POLY1305_KEYLEN 32
|
||||
#define POLY1305_TAGLEN 16
|
||||
#define POLY1305_KEYLEN 32
|
||||
#define POLY1305_TAGLEN 16
|
||||
|
||||
void poly1305_auth(uint8_t out[POLY1305_TAGLEN], const uint8_t *m, size_t inlen, const uint8_t key[POLY1305_KEYLEN]);
|
||||
|
||||
#endif /* POLY1305_H */
|
||||
#endif /* POLY1305_H */
|
||||
|
|
31
src/cipher.h
31
src/cipher.h
|
@ -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
|
||||
|
||||
|
|
186
src/conf.c
186
src/conf.c
|
@ -46,27 +46,31 @@ 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) {
|
||||
void init_configuration(splay_tree_t **config_tree) {
|
||||
*config_tree = splay_alloc_tree((splay_compare_t) config_compare, (splay_action_t) free_config);
|
||||
}
|
||||
|
||||
void exit_configuration(splay_tree_t ** config_tree) {
|
||||
void exit_configuration(splay_tree_t **config_tree) {
|
||||
splay_delete_tree(*config_tree);
|
||||
*config_tree = NULL;
|
||||
}
|
||||
|
@ -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->variable);
|
||||
free(cfg->value);
|
||||
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,8 +120,9 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,8 +130,9 @@ config_t *lookup_config_next(splay_tree_t *config_tree, const config_t *cfg) {
|
|||
}
|
||||
|
||||
bool get_config_bool(const config_t *cfg, bool *result) {
|
||||
if(!cfg)
|
||||
if(!cfg) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!strcasecmp(cfg->value, "yes")) {
|
||||
*result = true;
|
||||
|
@ -141,27 +143,30 @@ bool get_config_bool(const config_t *cfg, bool *result) {
|
|||
}
|
||||
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "\"yes\" or \"no\" expected for configuration variable %s in %s line %d",
|
||||
cfg->variable, cfg->file, cfg->line);
|
||||
cfg->variable, cfg->file, cfg->line);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
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);
|
||||
cfg->variable, cfg->file, cfg->line);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
@ -182,31 +188,32 @@ bool get_config_address(const config_t *cfg, struct addrinfo **result) {
|
|||
}
|
||||
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Hostname or IP address expected for configuration variable %s in %s line %d",
|
||||
cfg->variable, cfg->file, cfg->line);
|
||||
cfg->variable, cfg->file, cfg->line);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool get_config_subnet(const config_t *cfg, subnet_t ** result) {
|
||||
subnet_t subnet = {NULL};
|
||||
bool get_config_subnet(const config_t *cfg, subnet_t **result) {
|
||||
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",
|
||||
cfg->variable, cfg->file, cfg->line);
|
||||
cfg->variable, cfg->file, cfg->line);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Teach newbies what subnets are... */
|
||||
|
||||
if(((subnet.type == SUBNET_IPV4)
|
||||
&& !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.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)))) {
|
||||
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);
|
||||
cfg->variable, cfg->file, cfg->line);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -218,27 +225,32 @@ bool get_config_subnet(const config_t *cfg, subnet_t ** result) {
|
|||
/*
|
||||
Read exactly one line and strip the trailing newline if any.
|
||||
*/
|
||||
static char *readline(FILE * fp, char *buf, size_t buflen) {
|
||||
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)
|
||||
|
||||
if(fname)
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "%s `%s' on line %d while reading config file %s",
|
||||
err, variable, lineno, fname);
|
||||
err, variable, lineno, fname);
|
||||
else
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "%s `%s' in command line option %d",
|
||||
err, variable, lineno);
|
||||
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) {
|
||||
if(x) {
|
||||
char dname[PATH_MAX];
|
||||
snprintf(dname, sizeof dname, "%s" SLASH "conf.d", confbase);
|
||||
DIR *dir = opendir (dname);
|
||||
snprintf(dname, sizeof(dname), "%s" SLASH "conf.d", confbase);
|
||||
DIR *dir = opendir(dname);
|
||||
|
||||
// If we can find this dir
|
||||
if (dir) {
|
||||
if(dir) {
|
||||
struct dirent *ep;
|
||||
|
||||
// We list all the files in it
|
||||
while (x && (ep = readdir (dir))) {
|
||||
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(l > 5 && !strcmp(".conf", & ep->d_name[ l - 5 ])) {
|
||||
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);
|
||||
|
||||
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");
|
||||
|
||||
|
|
42
src/conf.h
42
src/conf.h
|
@ -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 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 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 *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
|
||||
|
|
|
@ -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)
|
||||
closesocket(c->socket);
|
||||
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);
|
||||
}
|
||||
|
@ -96,9 +105,9 @@ void connection_del(connection_t *c) {
|
|||
bool dump_connections(connection_t *cdump) {
|
||||
for list_each(connection_t, c, connection_list) {
|
||||
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));
|
||||
CONTROL, REQ_DUMP_CONNECTIONS,
|
||||
c->name, c->hostname, c->options, c->socket,
|
||||
bitfield_to_int(&c->status, sizeof(c->status)));
|
||||
}
|
||||
|
||||
return send_request(cdump, "%d %d", CONTROL, REQ_DUMP_CONNECTIONS);
|
||||
|
|
|
@ -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"
|
||||
|
@ -35,21 +35,22 @@
|
|||
#define OPTION_VERSION(x) ((x) >> 24) /* Top 8 bits are for protocol minor version */
|
||||
|
||||
typedef struct connection_status_t {
|
||||
unsigned int pinged:1; /* sent ping */
|
||||
unsigned int unused_active:1;
|
||||
unsigned int connecting:1; /* 1 if we are waiting for a non-blocking connect() to finish */
|
||||
unsigned int unused_termreq:1; /* the termination of this connection was requested */
|
||||
unsigned int remove_unused:1; /* Set to 1 if you want this connection removed */
|
||||
unsigned int timeout_unused:1; /* 1 if gotten timeout */
|
||||
unsigned int encryptout:1; /* 1 if we can encrypt outgoing traffic */
|
||||
unsigned int decryptin:1; /* 1 if we have to decrypt incoming traffic */
|
||||
unsigned int mst:1; /* 1 if this connection is part of a minimum spanning tree */
|
||||
unsigned int control:1; /* 1 if this is a control connection */
|
||||
unsigned int pcap:1; /* 1 if this is a control connection requesting packet capture */
|
||||
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 pinged: 1; /* sent ping */
|
||||
unsigned int unused_active: 1;
|
||||
unsigned int connecting: 1; /* 1 if we are waiting for a non-blocking connect() to finish */
|
||||
unsigned int unused_termreq: 1; /* the termination of this connection was requested */
|
||||
unsigned int remove_unused: 1; /* Set to 1 if you want this connection removed */
|
||||
unsigned int timeout_unused: 1; /* 1 if gotten timeout */
|
||||
unsigned int encryptout: 1; /* 1 if we can encrypt outgoing traffic */
|
||||
unsigned int decryptin: 1; /* 1 if we have to decrypt incoming traffic */
|
||||
unsigned int mst: 1; /* 1 if this connection is part of a minimum spanning tree */
|
||||
unsigned int control: 1; /* 1 if this is a control connection */
|
||||
unsigned int pcap: 1; /* 1 if this is a control connection requesting packet capture */
|
||||
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 tarpit: 1; /* 1 if the connection should be added to the tarpit */
|
||||
unsigned int unused: 17;
|
||||
} connection_status_t;
|
||||
|
||||
#include "ecdsa.h"
|
||||
|
@ -94,12 +95,13 @@ 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;
|
||||
io_t io; /* input/output event on this metadata connection */
|
||||
int tcplen; /* length of incoming TCPpacket */
|
||||
int sptpslen; /* length of incoming SPTPS packet */
|
||||
int sptpslen; /* length of incoming SPTPS packet */
|
||||
int allow_request; /* defined if there's only one request possible */
|
||||
|
||||
time_t last_ping_time; /* last time we saw some activity from the other end or pinged them */
|
||||
|
@ -112,10 +114,10 @@ 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 connection_t *new_connection(void) __attribute__((__malloc__));
|
||||
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
|
||||
|
|
149
src/control.c
149
src/control.c
|
@ -56,86 +56,95 @@ bool control_h(connection_t *c, const char *request) {
|
|||
return false;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case REQ_STOP:
|
||||
event_exit();
|
||||
return control_ok(c, REQ_STOP);
|
||||
switch(type) {
|
||||
case REQ_STOP:
|
||||
event_exit();
|
||||
return control_ok(c, REQ_STOP);
|
||||
|
||||
case REQ_DUMP_NODES:
|
||||
return dump_nodes(c);
|
||||
case REQ_DUMP_NODES:
|
||||
return dump_nodes(c);
|
||||
|
||||
case REQ_DUMP_EDGES:
|
||||
return dump_edges(c);
|
||||
case REQ_DUMP_EDGES:
|
||||
return dump_edges(c);
|
||||
|
||||
case REQ_DUMP_SUBNETS:
|
||||
return dump_subnets(c);
|
||||
case REQ_DUMP_SUBNETS:
|
||||
return dump_subnets(c);
|
||||
|
||||
case REQ_DUMP_CONNECTIONS:
|
||||
return dump_connections(c);
|
||||
case REQ_DUMP_CONNECTIONS:
|
||||
return dump_connections(c);
|
||||
|
||||
case REQ_PURGE:
|
||||
purge();
|
||||
return control_ok(c, REQ_PURGE);
|
||||
case REQ_PURGE:
|
||||
purge();
|
||||
return control_ok(c, REQ_PURGE);
|
||||
|
||||
case REQ_SET_DEBUG: {
|
||||
int new_level;
|
||||
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)
|
||||
debug_level = new_level;
|
||||
return true;
|
||||
case REQ_SET_DEBUG: {
|
||||
int new_level;
|
||||
|
||||
if(sscanf(request, "%*d %*d %d", &new_level) != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
case REQ_RETRY:
|
||||
retry();
|
||||
return control_ok(c, REQ_RETRY);
|
||||
send_request(c, "%d %d %d", CONTROL, REQ_SET_DEBUG, debug_level);
|
||||
|
||||
case REQ_RELOAD:
|
||||
logger(DEBUG_ALWAYS, LOG_NOTICE, "Got '%s' command", "reload");
|
||||
int result = reload_configuration();
|
||||
return control_return(c, REQ_RELOAD, result);
|
||||
if(new_level >= 0) {
|
||||
debug_level = new_level;
|
||||
}
|
||||
|
||||
case REQ_DISCONNECT: {
|
||||
char name[MAX_STRING_SIZE];
|
||||
bool found = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(sscanf(request, "%*d %*d " MAX_STRING, name) != 1)
|
||||
return control_return(c, REQ_DISCONNECT, -1);
|
||||
case REQ_RETRY:
|
||||
retry();
|
||||
return control_ok(c, REQ_RETRY);
|
||||
|
||||
for list_each(connection_t, other, connection_list) {
|
||||
if(strcmp(other->name, name))
|
||||
continue;
|
||||
terminate_connection(other, other->edge);
|
||||
found = true;
|
||||
case REQ_RELOAD:
|
||||
logger(DEBUG_ALWAYS, LOG_NOTICE, "Got '%s' command", "reload");
|
||||
int result = reload_configuration();
|
||||
return control_return(c, REQ_RELOAD, result);
|
||||
|
||||
case REQ_DISCONNECT: {
|
||||
char name[MAX_STRING_SIZE];
|
||||
bool found = false;
|
||||
|
||||
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)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return control_return(c, REQ_DISCONNECT, found ? 0 : -2);
|
||||
terminate_connection(other, other->edge);
|
||||
found = true;
|
||||
}
|
||||
|
||||
case REQ_DUMP_TRAFFIC:
|
||||
return dump_traffic(c);
|
||||
return control_return(c, REQ_DISCONNECT, found ? 0 : -2);
|
||||
}
|
||||
|
||||
case REQ_PCAP:
|
||||
sscanf(request, "%*d %*d %d", &c->outmaclength);
|
||||
c->status.pcap = true;
|
||||
pcap = true;
|
||||
return true;
|
||||
case REQ_DUMP_TRAFFIC:
|
||||
return dump_traffic(c);
|
||||
|
||||
case REQ_LOG:
|
||||
sscanf(request, "%*d %*d %d", &c->outcompression);
|
||||
c->status.log = true;
|
||||
logcontrol = true;
|
||||
return true;
|
||||
case REQ_PCAP:
|
||||
sscanf(request, "%*d %*d %d", &c->outmaclength);
|
||||
c->status.pcap = true;
|
||||
pcap = true;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return send_request(c, "%d %d", CONTROL, REQ_INVALID);
|
||||
case REQ_LOG:
|
||||
sscanf(request, "%*d %*d %d", &c->outcompression);
|
||||
c->status.log = true;
|
||||
logcontrol = true;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return send_request(c, "%d %d", CONTROL, REQ_INVALID);
|
||||
}
|
||||
}
|
||||
|
||||
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,21 +159,24 @@ 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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
12
src/crypto.h
12
src/crypto.h
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
@ -69,44 +70,51 @@ static bool setup_device(void) {
|
|||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; ; i++) {
|
||||
len = sizeof adapterid;
|
||||
if(RegEnumKeyEx(key, i, adapterid, &len, 0, 0, 0, NULL))
|
||||
for(i = 0; ; i++) {
|
||||
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.
|
||||
|
@ -140,7 +150,7 @@ static bool setup_device(void) {
|
|||
|
||||
/* The parent opens the tap device for writing. */
|
||||
|
||||
device_handle = CreateFile(tapname, GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM , 0);
|
||||
device_handle = CreateFile(tapname, GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0);
|
||||
|
||||
if(device_handle == INVALID_HANDLE_VALUE) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Could not open Windows tap device %s (%s) for writing: %s", device, iface, winerror(GetLastError()));
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -232,14 +244,14 @@ static bool read_packet(vpn_packet_t *packet) {
|
|||
|
||||
if((inlen = read(sp[0], DATA(packet), MTU)) <= 0) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info,
|
||||
device, strerror(errno));
|
||||
device, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
packet->len = inlen;
|
||||
|
||||
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len,
|
||||
device_info);
|
||||
device_info);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -248,9 +260,9 @@ static bool write_packet(vpn_packet_t *packet) {
|
|||
long outlen;
|
||||
|
||||
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s",
|
||||
packet->len, device_info);
|
||||
packet->len, device_info);
|
||||
|
||||
if(!WriteFile (device_handle, DATA(packet), packet->len, &outlen, NULL)) {
|
||||
if(!WriteFile(device_handle, DATA(packet), packet->len, &outlen, NULL)) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, device, winerror(GetLastError()));
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
26
src/digest.h
26
src/digest.h
|
@ -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,25 +20,22 @@
|
|||
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
|
||||
|
||||
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 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 *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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
28
src/dropin.h
28
src/dropin.h
|
@ -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
|
||||
|
@ -40,20 +40,20 @@ extern int nanosleep(const struct timespec *req, struct timespec *rem);
|
|||
|
||||
#ifndef timeradd
|
||||
#define timeradd(a, b, r) do {\
|
||||
(r)->tv_sec = (a)->tv_sec + (b)->tv_sec;\
|
||||
(r)->tv_usec = (a)->tv_usec + (b)->tv_usec;\
|
||||
if((r)->tv_usec >= 1000000)\
|
||||
(r)->tv_sec++, (r)->tv_usec -= 1000000;\
|
||||
} while (0)
|
||||
(r)->tv_sec = (a)->tv_sec + (b)->tv_sec;\
|
||||
(r)->tv_usec = (a)->tv_usec + (b)->tv_usec;\
|
||||
if((r)->tv_usec >= 1000000)\
|
||||
(r)->tv_sec++, (r)->tv_usec -= 1000000;\
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef timersub
|
||||
#define timersub(a, b, r) do {\
|
||||
(r)->tv_sec = (a)->tv_sec - (b)->tv_sec;\
|
||||
(r)->tv_usec = (a)->tv_usec - (b)->tv_usec;\
|
||||
if((r)->tv_usec < 0)\
|
||||
(r)->tv_sec--, (r)->tv_usec += 1000000;\
|
||||
} while (0)
|
||||
(r)->tv_sec = (a)->tv_sec - (b)->tv_sec;\
|
||||
(r)->tv_usec = (a)->tv_usec - (b)->tv_usec;\
|
||||
if((r)->tv_usec < 0)\
|
||||
(r)->tv_sec--, (r)->tv_usec += 1000000;\
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MINGW
|
||||
|
@ -67,4 +67,4 @@ extern int nanosleep(const struct timespec *req, struct timespec *rem);
|
|||
#define EAI_SYSTEM 0
|
||||
#endif
|
||||
|
||||
#endif /* __DROPIN_H__ */
|
||||
#endif
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
12
src/ecdh.h
12
src/ecdh.h
|
@ -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,18 +20,15 @@
|
|||
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
|
||||
|
||||
extern ecdh_t *ecdh_generate_public(void *pubkey) __attribute__ ((__malloc__));
|
||||
extern bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) __attribute__ ((__warn_unused_result__));
|
||||
extern ecdh_t *ecdh_generate_public(void *pubkey) __attribute__((__malloc__));
|
||||
extern bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) __attribute__((__warn_unused_result__));
|
||||
extern void ecdh_free(ecdh_t *ecdh);
|
||||
|
||||
#endif
|
||||
|
|
18
src/ecdsa.h
18
src/ecdsa.h
|
@ -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,20 +20,17 @@
|
|||
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
|
||||
|
||||
extern ecdsa_t *ecdsa_set_base64_public_key(const char *p) __attribute__ ((__malloc__));
|
||||
extern ecdsa_t *ecdsa_set_base64_public_key(const char *p) __attribute__((__malloc__));
|
||||
extern char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa);
|
||||
extern ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) __attribute__ ((__malloc__));
|
||||
extern ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) __attribute__ ((__malloc__));
|
||||
extern ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) __attribute__((__malloc__));
|
||||
extern ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) __attribute__((__malloc__));
|
||||
extern size_t ecdsa_size(ecdsa_t *ecdsa);
|
||||
extern bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t inlen, void *out) __attribute__ ((__warn_unused_result__));
|
||||
extern bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t inlen, const void *out) __attribute__ ((__warn_unused_result__));
|
||||
extern bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t inlen, void *out) __attribute__((__warn_unused_result__));
|
||||
extern bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t inlen, const void *out) __attribute__((__warn_unused_result__));
|
||||
extern bool ecdsa_active(ecdsa_t *ecdsa);
|
||||
extern void ecdsa_free(ecdsa_t *ecdsa);
|
||||
|
||||
|
|
|
@ -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,13 +20,10 @@
|
|||
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__));
|
||||
extern bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp) __attribute__ ((__warn_unused_result__));
|
||||
extern bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp) __attribute__ ((__warn_unused_result__));
|
||||
extern ecdsa_t *ecdsa_generate(void) __attribute__((__malloc__));
|
||||
extern bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp) __attribute__((__warn_unused_result__));
|
||||
extern bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp) __attribute__((__warn_unused_result__));
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -4,15 +4,15 @@
|
|||
#include <stddef.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#if defined(ED25519_BUILD_DLL)
|
||||
#define ED25519_DECLSPEC __declspec(dllexport)
|
||||
#elif defined(ED25519_DLL)
|
||||
#define ED25519_DECLSPEC __declspec(dllimport)
|
||||
#else
|
||||
#define ED25519_DECLSPEC
|
||||
#endif
|
||||
#if defined(ED25519_BUILD_DLL)
|
||||
#define ED25519_DECLSPEC __declspec(dllexport)
|
||||
#elif defined(ED25519_DLL)
|
||||
#define ED25519_DECLSPEC __declspec(dllimport)
|
||||
#else
|
||||
#define ED25519_DECLSPEC
|
||||
#define ED25519_DECLSPEC
|
||||
#endif
|
||||
#else
|
||||
#define ED25519_DECLSPEC
|
||||
#endif
|
||||
|
||||
|
||||
|
|
2348
src/ed25519/fe.c
2348
src/ed25519/fe.c
File diff suppressed because it is too large
Load diff
|
@ -1,75 +1,75 @@
|
|||
#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
|
||||
#include <stdint.h>
|
||||
#define FIXEDINT_H_INCLUDED
|
||||
|
||||
#if defined(__WATCOMC__) && __WATCOMC__ >= 1250 && !defined(UINT64_C)
|
||||
#include <limits.h>
|
||||
#define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX))
|
||||
#endif
|
||||
#if defined(__WATCOMC__) && __WATCOMC__ >= 1250 && !defined(UINT64_C)
|
||||
#include <limits.h>
|
||||
#define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef FIXEDINT_H_INCLUDED
|
||||
#define FIXEDINT_H_INCLUDED
|
||||
#define FIXEDINT_H_INCLUDED
|
||||
|
||||
/* (u)int32_t */
|
||||
#ifndef uint32_t
|
||||
#if (ULONG_MAX == 0xffffffffUL)
|
||||
typedef unsigned long uint32_t;
|
||||
#elif (UINT_MAX == 0xffffffffUL)
|
||||
typedef unsigned int uint32_t;
|
||||
#elif (USHRT_MAX == 0xffffffffUL)
|
||||
typedef unsigned short uint32_t;
|
||||
#endif
|
||||
#endif
|
||||
/* (u)int32_t */
|
||||
#ifndef uint32_t
|
||||
#if (ULONG_MAX == 0xffffffffUL)
|
||||
typedef unsigned long uint32_t;
|
||||
#elif (UINT_MAX == 0xffffffffUL)
|
||||
typedef unsigned int uint32_t;
|
||||
#elif (USHRT_MAX == 0xffffffffUL)
|
||||
typedef unsigned short uint32_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef int32_t
|
||||
#if (LONG_MAX == 0x7fffffffL)
|
||||
typedef signed long int32_t;
|
||||
#elif (INT_MAX == 0x7fffffffL)
|
||||
typedef signed int int32_t;
|
||||
#elif (SHRT_MAX == 0x7fffffffL)
|
||||
typedef signed short int32_t;
|
||||
#endif
|
||||
#endif
|
||||
#ifndef int32_t
|
||||
#if (LONG_MAX == 0x7fffffffL)
|
||||
typedef signed long int32_t;
|
||||
#elif (INT_MAX == 0x7fffffffL)
|
||||
typedef signed int int32_t;
|
||||
#elif (SHRT_MAX == 0x7fffffffL)
|
||||
typedef signed short int32_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* (u)int64_t */
|
||||
#if (defined(__STDC__) && defined(__STDC_VERSION__) && __STDC__ && __STDC_VERSION__ >= 199901L)
|
||||
typedef long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
/* (u)int64_t */
|
||||
#if (defined(__STDC__) && defined(__STDC_VERSION__) && __STDC__ && __STDC_VERSION__ >= 199901L)
|
||||
typedef long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
|
||||
#define UINT64_C(v) v ##ULL
|
||||
#define INT64_C(v) v ##LL
|
||||
#elif defined(__GNUC__)
|
||||
__extension__ typedef long long int64_t;
|
||||
__extension__ typedef unsigned long long uint64_t;
|
||||
#define UINT64_C(v) v ##ULL
|
||||
#define INT64_C(v) v ##LL
|
||||
#elif defined(__GNUC__)
|
||||
__extension__ typedef long long int64_t;
|
||||
__extension__ typedef unsigned long long uint64_t;
|
||||
|
||||
#define UINT64_C(v) v ##ULL
|
||||
#define INT64_C(v) v ##LL
|
||||
#elif defined(__MWERKS__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__APPLE_CC__) || defined(_LONG_LONG) || defined(_CRAYC)
|
||||
typedef long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
#define UINT64_C(v) v ##ULL
|
||||
#define INT64_C(v) v ##LL
|
||||
#elif defined(__MWERKS__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__APPLE_CC__) || defined(_LONG_LONG) || defined(_CRAYC)
|
||||
typedef long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
|
||||
#define UINT64_C(v) v ##ULL
|
||||
#define INT64_C(v) v ##LL
|
||||
#elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined(__BORLANDC__) && __BORLANDC__ > 0x460) || defined(__alpha) || defined(__DECC)
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#define UINT64_C(v) v ##ULL
|
||||
#define INT64_C(v) v ##LL
|
||||
#elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined(__BORLANDC__) && __BORLANDC__ > 0x460) || defined(__alpha) || defined(__DECC)
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
|
||||
#define UINT64_C(v) v ##UI64
|
||||
#define INT64_C(v) v ##I64
|
||||
#endif
|
||||
#define UINT64_C(v) v ##UI64
|
||||
#define INT64_C(v) v ##I64
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static inline unsigned char shlu8(unsigned char a, uint32_t b) {
|
||||
|
|
586
src/ed25519/ge.c
586
src/ed25519/ge.c
|
@ -7,54 +7,54 @@ r = p + q
|
|||
*/
|
||||
|
||||
void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
|
||||
fe t0;
|
||||
fe_add(r->X, p->Y, p->X);
|
||||
fe_sub(r->Y, p->Y, p->X);
|
||||
fe_mul(r->Z, r->X, q->YplusX);
|
||||
fe_mul(r->Y, r->Y, q->YminusX);
|
||||
fe_mul(r->T, q->T2d, p->T);
|
||||
fe_mul(r->X, p->Z, q->Z);
|
||||
fe_add(t0, r->X, r->X);
|
||||
fe_sub(r->X, r->Z, r->Y);
|
||||
fe_add(r->Y, r->Z, r->Y);
|
||||
fe_add(r->Z, t0, r->T);
|
||||
fe_sub(r->T, t0, r->T);
|
||||
fe t0;
|
||||
fe_add(r->X, p->Y, p->X);
|
||||
fe_sub(r->Y, p->Y, p->X);
|
||||
fe_mul(r->Z, r->X, q->YplusX);
|
||||
fe_mul(r->Y, r->Y, q->YminusX);
|
||||
fe_mul(r->T, q->T2d, p->T);
|
||||
fe_mul(r->X, p->Z, q->Z);
|
||||
fe_add(t0, r->X, r->X);
|
||||
fe_sub(r->X, r->Z, r->Y);
|
||||
fe_add(r->Y, r->Z, r->Y);
|
||||
fe_add(r->Z, t0, r->T);
|
||||
fe_sub(r->T, t0, r->T);
|
||||
}
|
||||
|
||||
|
||||
static void slide(signed char *r, const unsigned char *a) {
|
||||
int i;
|
||||
int b;
|
||||
int k;
|
||||
int i;
|
||||
int b;
|
||||
int k;
|
||||
|
||||
for (i = 0; i < 256; ++i) {
|
||||
r[i] = 1 & (a[i >> 3] >> (i & 7));
|
||||
}
|
||||
for(i = 0; i < 256; ++i) {
|
||||
r[i] = 1 & (a[i >> 3] >> (i & 7));
|
||||
}
|
||||
|
||||
for (i = 0; i < 256; ++i)
|
||||
if (r[i]) {
|
||||
for (b = 1; b <= 6 && i + b < 256; ++b) {
|
||||
if (r[i + b]) {
|
||||
if (r[i] + (r[i + b] << b) <= 15) {
|
||||
r[i] += r[i + b] << b;
|
||||
r[i + b] = 0;
|
||||
} else if (r[i] - (r[i + b] << b) >= -15) {
|
||||
r[i] -= r[i + b] << b;
|
||||
for(i = 0; i < 256; ++i)
|
||||
if(r[i]) {
|
||||
for(b = 1; b <= 6 && i + b < 256; ++b) {
|
||||
if(r[i + b]) {
|
||||
if(r[i] + (r[i + b] << b) <= 15) {
|
||||
r[i] += r[i + b] << b;
|
||||
r[i + b] = 0;
|
||||
} else if(r[i] - (r[i + b] << b) >= -15) {
|
||||
r[i] -= r[i + b] << b;
|
||||
|
||||
for (k = i + b; k < 256; ++k) {
|
||||
if (!r[k]) {
|
||||
r[k] = 1;
|
||||
break;
|
||||
}
|
||||
for(k = i + b; k < 256; ++k) {
|
||||
if(!r[k]) {
|
||||
r[k] = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
r[k] = 0;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
r[k] = 0;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -65,119 +65,119 @@ B is the Ed25519 base point (x,4/5) with x positive.
|
|||
*/
|
||||
|
||||
void ge_double_scalarmult_vartime(ge_p2 *r, const unsigned char *a, const ge_p3 *A, const unsigned char *b) {
|
||||
signed char aslide[256];
|
||||
signed char bslide[256];
|
||||
ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */
|
||||
ge_p1p1 t;
|
||||
ge_p3 u;
|
||||
ge_p3 A2;
|
||||
int i;
|
||||
slide(aslide, a);
|
||||
slide(bslide, b);
|
||||
ge_p3_to_cached(&Ai[0], A);
|
||||
ge_p3_dbl(&t, A);
|
||||
ge_p1p1_to_p3(&A2, &t);
|
||||
ge_add(&t, &A2, &Ai[0]);
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_p3_to_cached(&Ai[1], &u);
|
||||
ge_add(&t, &A2, &Ai[1]);
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_p3_to_cached(&Ai[2], &u);
|
||||
ge_add(&t, &A2, &Ai[2]);
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_p3_to_cached(&Ai[3], &u);
|
||||
ge_add(&t, &A2, &Ai[3]);
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_p3_to_cached(&Ai[4], &u);
|
||||
ge_add(&t, &A2, &Ai[4]);
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_p3_to_cached(&Ai[5], &u);
|
||||
ge_add(&t, &A2, &Ai[5]);
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_p3_to_cached(&Ai[6], &u);
|
||||
ge_add(&t, &A2, &Ai[6]);
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_p3_to_cached(&Ai[7], &u);
|
||||
ge_p2_0(r);
|
||||
signed char aslide[256];
|
||||
signed char bslide[256];
|
||||
ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */
|
||||
ge_p1p1 t;
|
||||
ge_p3 u;
|
||||
ge_p3 A2;
|
||||
int i;
|
||||
slide(aslide, a);
|
||||
slide(bslide, b);
|
||||
ge_p3_to_cached(&Ai[0], A);
|
||||
ge_p3_dbl(&t, A);
|
||||
ge_p1p1_to_p3(&A2, &t);
|
||||
ge_add(&t, &A2, &Ai[0]);
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_p3_to_cached(&Ai[1], &u);
|
||||
ge_add(&t, &A2, &Ai[1]);
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_p3_to_cached(&Ai[2], &u);
|
||||
ge_add(&t, &A2, &Ai[2]);
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_p3_to_cached(&Ai[3], &u);
|
||||
ge_add(&t, &A2, &Ai[3]);
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_p3_to_cached(&Ai[4], &u);
|
||||
ge_add(&t, &A2, &Ai[4]);
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_p3_to_cached(&Ai[5], &u);
|
||||
ge_add(&t, &A2, &Ai[5]);
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_p3_to_cached(&Ai[6], &u);
|
||||
ge_add(&t, &A2, &Ai[6]);
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_p3_to_cached(&Ai[7], &u);
|
||||
ge_p2_0(r);
|
||||
|
||||
for (i = 255; i >= 0; --i) {
|
||||
if (aslide[i] || bslide[i]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(i = 255; i >= 0; --i) {
|
||||
if(aslide[i] || bslide[i]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (; i >= 0; --i) {
|
||||
ge_p2_dbl(&t, r);
|
||||
for(; i >= 0; --i) {
|
||||
ge_p2_dbl(&t, r);
|
||||
|
||||
if (aslide[i] > 0) {
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_add(&t, &u, &Ai[aslide[i] / 2]);
|
||||
} else if (aslide[i] < 0) {
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]);
|
||||
}
|
||||
if(aslide[i] > 0) {
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_add(&t, &u, &Ai[aslide[i] / 2]);
|
||||
} else if(aslide[i] < 0) {
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]);
|
||||
}
|
||||
|
||||
if (bslide[i] > 0) {
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_madd(&t, &u, &Bi[bslide[i] / 2]);
|
||||
} else if (bslide[i] < 0) {
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_msub(&t, &u, &Bi[(-bslide[i]) / 2]);
|
||||
}
|
||||
if(bslide[i] > 0) {
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_madd(&t, &u, &Bi[bslide[i] / 2]);
|
||||
} else if(bslide[i] < 0) {
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_msub(&t, &u, &Bi[(-bslide[i]) / 2]);
|
||||
}
|
||||
|
||||
ge_p1p1_to_p2(r, &t);
|
||||
}
|
||||
ge_p1p1_to_p2(r, &t);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const fe d = {
|
||||
-10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116
|
||||
};
|
||||
-10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116
|
||||
};
|
||||
|
||||
static const fe sqrtm1 = {
|
||||
-32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482
|
||||
};
|
||||
-32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482
|
||||
};
|
||||
|
||||
int ge_frombytes_negate_vartime(ge_p3 *h, const unsigned char *s) {
|
||||
fe u;
|
||||
fe v;
|
||||
fe v3;
|
||||
fe vxx;
|
||||
fe check;
|
||||
fe_frombytes(h->Y, s);
|
||||
fe_1(h->Z);
|
||||
fe_sq(u, h->Y);
|
||||
fe_mul(v, u, d);
|
||||
fe_sub(u, u, h->Z); /* u = y^2-1 */
|
||||
fe_add(v, v, h->Z); /* v = dy^2+1 */
|
||||
fe_sq(v3, v);
|
||||
fe_mul(v3, v3, v); /* v3 = v^3 */
|
||||
fe_sq(h->X, v3);
|
||||
fe_mul(h->X, h->X, v);
|
||||
fe_mul(h->X, h->X, u); /* x = uv^7 */
|
||||
fe_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */
|
||||
fe_mul(h->X, h->X, v3);
|
||||
fe_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */
|
||||
fe_sq(vxx, h->X);
|
||||
fe_mul(vxx, vxx, v);
|
||||
fe_sub(check, vxx, u); /* vx^2-u */
|
||||
fe u;
|
||||
fe v;
|
||||
fe v3;
|
||||
fe vxx;
|
||||
fe check;
|
||||
fe_frombytes(h->Y, s);
|
||||
fe_1(h->Z);
|
||||
fe_sq(u, h->Y);
|
||||
fe_mul(v, u, d);
|
||||
fe_sub(u, u, h->Z); /* u = y^2-1 */
|
||||
fe_add(v, v, h->Z); /* v = dy^2+1 */
|
||||
fe_sq(v3, v);
|
||||
fe_mul(v3, v3, v); /* v3 = v^3 */
|
||||
fe_sq(h->X, v3);
|
||||
fe_mul(h->X, h->X, v);
|
||||
fe_mul(h->X, h->X, u); /* x = uv^7 */
|
||||
fe_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */
|
||||
fe_mul(h->X, h->X, v3);
|
||||
fe_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */
|
||||
fe_sq(vxx, h->X);
|
||||
fe_mul(vxx, vxx, v);
|
||||
fe_sub(check, vxx, u); /* vx^2-u */
|
||||
|
||||
if (fe_isnonzero(check)) {
|
||||
fe_add(check, vxx, u); /* vx^2+u */
|
||||
if(fe_isnonzero(check)) {
|
||||
fe_add(check, vxx, u); /* vx^2+u */
|
||||
|
||||
if (fe_isnonzero(check)) {
|
||||
return -1;
|
||||
}
|
||||
if(fe_isnonzero(check)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
fe_mul(h->X, h->X, sqrtm1);
|
||||
}
|
||||
fe_mul(h->X, h->X, sqrtm1);
|
||||
}
|
||||
|
||||
if (fe_isnegative(h->X) == (s[31] >> 7)) {
|
||||
fe_neg(h->X, h->X);
|
||||
}
|
||||
if(fe_isnegative(h->X) == (s[31] >> 7)) {
|
||||
fe_neg(h->X, h->X);
|
||||
}
|
||||
|
||||
fe_mul(h->T, h->X, h->Y);
|
||||
return 0;
|
||||
fe_mul(h->T, h->X, h->Y);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -186,17 +186,17 @@ r = p + q
|
|||
*/
|
||||
|
||||
void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) {
|
||||
fe t0;
|
||||
fe_add(r->X, p->Y, p->X);
|
||||
fe_sub(r->Y, p->Y, p->X);
|
||||
fe_mul(r->Z, r->X, q->yplusx);
|
||||
fe_mul(r->Y, r->Y, q->yminusx);
|
||||
fe_mul(r->T, q->xy2d, p->T);
|
||||
fe_add(t0, p->Z, p->Z);
|
||||
fe_sub(r->X, r->Z, r->Y);
|
||||
fe_add(r->Y, r->Z, r->Y);
|
||||
fe_add(r->Z, t0, r->T);
|
||||
fe_sub(r->T, t0, r->T);
|
||||
fe t0;
|
||||
fe_add(r->X, p->Y, p->X);
|
||||
fe_sub(r->Y, p->Y, p->X);
|
||||
fe_mul(r->Z, r->X, q->yplusx);
|
||||
fe_mul(r->Y, r->Y, q->yminusx);
|
||||
fe_mul(r->T, q->xy2d, p->T);
|
||||
fe_add(t0, p->Z, p->Z);
|
||||
fe_sub(r->X, r->Z, r->Y);
|
||||
fe_add(r->Y, r->Z, r->Y);
|
||||
fe_add(r->Z, t0, r->T);
|
||||
fe_sub(r->T, t0, r->T);
|
||||
}
|
||||
|
||||
|
||||
|
@ -205,18 +205,18 @@ r = p - q
|
|||
*/
|
||||
|
||||
void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) {
|
||||
fe t0;
|
||||
fe t0;
|
||||
|
||||
fe_add(r->X, p->Y, p->X);
|
||||
fe_sub(r->Y, p->Y, p->X);
|
||||
fe_mul(r->Z, r->X, q->yminusx);
|
||||
fe_mul(r->Y, r->Y, q->yplusx);
|
||||
fe_mul(r->T, q->xy2d, p->T);
|
||||
fe_add(t0, p->Z, p->Z);
|
||||
fe_sub(r->X, r->Z, r->Y);
|
||||
fe_add(r->Y, r->Z, r->Y);
|
||||
fe_sub(r->Z, t0, r->T);
|
||||
fe_add(r->T, t0, r->T);
|
||||
fe_add(r->X, p->Y, p->X);
|
||||
fe_sub(r->Y, p->Y, p->X);
|
||||
fe_mul(r->Z, r->X, q->yminusx);
|
||||
fe_mul(r->Y, r->Y, q->yplusx);
|
||||
fe_mul(r->T, q->xy2d, p->T);
|
||||
fe_add(t0, p->Z, p->Z);
|
||||
fe_sub(r->X, r->Z, r->Y);
|
||||
fe_add(r->Y, r->Z, r->Y);
|
||||
fe_sub(r->Z, t0, r->T);
|
||||
fe_add(r->T, t0, r->T);
|
||||
}
|
||||
|
||||
|
||||
|
@ -225,9 +225,9 @@ r = p
|
|||
*/
|
||||
|
||||
void ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) {
|
||||
fe_mul(r->X, p->X, p->T);
|
||||
fe_mul(r->Y, p->Y, p->Z);
|
||||
fe_mul(r->Z, p->Z, p->T);
|
||||
fe_mul(r->X, p->X, p->T);
|
||||
fe_mul(r->Y, p->Y, p->Z);
|
||||
fe_mul(r->Z, p->Z, p->T);
|
||||
}
|
||||
|
||||
|
||||
|
@ -237,17 +237,17 @@ r = p
|
|||
*/
|
||||
|
||||
void ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p) {
|
||||
fe_mul(r->X, p->X, p->T);
|
||||
fe_mul(r->Y, p->Y, p->Z);
|
||||
fe_mul(r->Z, p->Z, p->T);
|
||||
fe_mul(r->T, p->X, p->Y);
|
||||
fe_mul(r->X, p->X, p->T);
|
||||
fe_mul(r->Y, p->Y, p->Z);
|
||||
fe_mul(r->Z, p->Z, p->T);
|
||||
fe_mul(r->T, p->X, p->Y);
|
||||
}
|
||||
|
||||
|
||||
void ge_p2_0(ge_p2 *h) {
|
||||
fe_0(h->X);
|
||||
fe_1(h->Y);
|
||||
fe_1(h->Z);
|
||||
fe_0(h->X);
|
||||
fe_1(h->Y);
|
||||
fe_1(h->Z);
|
||||
}
|
||||
|
||||
|
||||
|
@ -257,25 +257,25 @@ r = 2 * p
|
|||
*/
|
||||
|
||||
void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p) {
|
||||
fe t0;
|
||||
fe t0;
|
||||
|
||||
fe_sq(r->X, p->X);
|
||||
fe_sq(r->Z, p->Y);
|
||||
fe_sq2(r->T, p->Z);
|
||||
fe_add(r->Y, p->X, p->Y);
|
||||
fe_sq(t0, r->Y);
|
||||
fe_add(r->Y, r->Z, r->X);
|
||||
fe_sub(r->Z, r->Z, r->X);
|
||||
fe_sub(r->X, t0, r->Y);
|
||||
fe_sub(r->T, r->T, r->Z);
|
||||
fe_sq(r->X, p->X);
|
||||
fe_sq(r->Z, p->Y);
|
||||
fe_sq2(r->T, p->Z);
|
||||
fe_add(r->Y, p->X, p->Y);
|
||||
fe_sq(t0, r->Y);
|
||||
fe_add(r->Y, r->Z, r->X);
|
||||
fe_sub(r->Z, r->Z, r->X);
|
||||
fe_sub(r->X, t0, r->Y);
|
||||
fe_sub(r->T, r->T, r->Z);
|
||||
}
|
||||
|
||||
|
||||
void ge_p3_0(ge_p3 *h) {
|
||||
fe_0(h->X);
|
||||
fe_1(h->Y);
|
||||
fe_1(h->Z);
|
||||
fe_0(h->T);
|
||||
fe_0(h->X);
|
||||
fe_1(h->Y);
|
||||
fe_1(h->Z);
|
||||
fe_0(h->T);
|
||||
}
|
||||
|
||||
|
||||
|
@ -284,9 +284,9 @@ r = 2 * p
|
|||
*/
|
||||
|
||||
void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p) {
|
||||
ge_p2 q;
|
||||
ge_p3_to_p2(&q, p);
|
||||
ge_p2_dbl(r, &q);
|
||||
ge_p2 q;
|
||||
ge_p3_to_p2(&q, p);
|
||||
ge_p2_dbl(r, &q);
|
||||
}
|
||||
|
||||
|
||||
|
@ -296,14 +296,14 @@ r = p
|
|||
*/
|
||||
|
||||
static const fe d2 = {
|
||||
-21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199
|
||||
};
|
||||
-21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199
|
||||
};
|
||||
|
||||
void ge_p3_to_cached(ge_cached *r, const ge_p3 *p) {
|
||||
fe_add(r->YplusX, p->Y, p->X);
|
||||
fe_sub(r->YminusX, p->Y, p->X);
|
||||
fe_copy(r->Z, p->Z);
|
||||
fe_mul(r->T2d, p->T, d2);
|
||||
fe_add(r->YplusX, p->Y, p->X);
|
||||
fe_sub(r->YminusX, p->Y, p->X);
|
||||
fe_copy(r->Z, p->Z);
|
||||
fe_mul(r->T2d, p->T, d2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -312,66 +312,66 @@ r = p
|
|||
*/
|
||||
|
||||
void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p) {
|
||||
fe_copy(r->X, p->X);
|
||||
fe_copy(r->Y, p->Y);
|
||||
fe_copy(r->Z, p->Z);
|
||||
fe_copy(r->X, p->X);
|
||||
fe_copy(r->Y, p->Y);
|
||||
fe_copy(r->Z, p->Z);
|
||||
}
|
||||
|
||||
|
||||
void ge_p3_tobytes(unsigned char *s, const ge_p3 *h) {
|
||||
fe recip;
|
||||
fe x;
|
||||
fe y;
|
||||
fe_invert(recip, h->Z);
|
||||
fe_mul(x, h->X, recip);
|
||||
fe_mul(y, h->Y, recip);
|
||||
fe_tobytes(s, y);
|
||||
s[31] ^= fe_isnegative(x) << 7;
|
||||
fe recip;
|
||||
fe x;
|
||||
fe y;
|
||||
fe_invert(recip, h->Z);
|
||||
fe_mul(x, h->X, recip);
|
||||
fe_mul(y, h->Y, recip);
|
||||
fe_tobytes(s, y);
|
||||
s[31] ^= fe_isnegative(x) << 7;
|
||||
}
|
||||
|
||||
|
||||
static unsigned char equal(signed char b, signed char c) {
|
||||
unsigned char ub = b;
|
||||
unsigned char uc = c;
|
||||
unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */
|
||||
uint64_t y = x; /* 0: yes; 1..255: no */
|
||||
y -= 1; /* large: yes; 0..254: no */
|
||||
y >>= 63; /* 1: yes; 0: no */
|
||||
return (unsigned char) y;
|
||||
unsigned char ub = b;
|
||||
unsigned char uc = c;
|
||||
unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */
|
||||
uint64_t y = x; /* 0: yes; 1..255: no */
|
||||
y -= 1; /* large: yes; 0..254: no */
|
||||
y >>= 63; /* 1: yes; 0: no */
|
||||
return (unsigned char) y;
|
||||
}
|
||||
|
||||
static unsigned char negative(signed char b) {
|
||||
uint64_t x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */
|
||||
x >>= 63; /* 1: yes; 0: no */
|
||||
return (unsigned char) x;
|
||||
uint64_t x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */
|
||||
x >>= 63; /* 1: yes; 0: no */
|
||||
return (unsigned char) x;
|
||||
}
|
||||
|
||||
static void cmov(ge_precomp *t, ge_precomp *u, unsigned char b) {
|
||||
fe_cmov(t->yplusx, u->yplusx, b);
|
||||
fe_cmov(t->yminusx, u->yminusx, b);
|
||||
fe_cmov(t->xy2d, u->xy2d, b);
|
||||
fe_cmov(t->yplusx, u->yplusx, b);
|
||||
fe_cmov(t->yminusx, u->yminusx, b);
|
||||
fe_cmov(t->xy2d, u->xy2d, b);
|
||||
}
|
||||
|
||||
|
||||
static void select(ge_precomp *t, int pos, signed char b) {
|
||||
ge_precomp minust;
|
||||
unsigned char bnegative = negative(b);
|
||||
unsigned char babs = b - shlu8(((-bnegative) & b), 1);
|
||||
fe_1(t->yplusx);
|
||||
fe_1(t->yminusx);
|
||||
fe_0(t->xy2d);
|
||||
cmov(t, &base[pos][0], equal(babs, 1));
|
||||
cmov(t, &base[pos][1], equal(babs, 2));
|
||||
cmov(t, &base[pos][2], equal(babs, 3));
|
||||
cmov(t, &base[pos][3], equal(babs, 4));
|
||||
cmov(t, &base[pos][4], equal(babs, 5));
|
||||
cmov(t, &base[pos][5], equal(babs, 6));
|
||||
cmov(t, &base[pos][6], equal(babs, 7));
|
||||
cmov(t, &base[pos][7], equal(babs, 8));
|
||||
fe_copy(minust.yplusx, t->yminusx);
|
||||
fe_copy(minust.yminusx, t->yplusx);
|
||||
fe_neg(minust.xy2d, t->xy2d);
|
||||
cmov(t, &minust, bnegative);
|
||||
ge_precomp minust;
|
||||
unsigned char bnegative = negative(b);
|
||||
unsigned char babs = b - shlu8(((-bnegative) & b), 1);
|
||||
fe_1(t->yplusx);
|
||||
fe_1(t->yminusx);
|
||||
fe_0(t->xy2d);
|
||||
cmov(t, &base[pos][0], equal(babs, 1));
|
||||
cmov(t, &base[pos][1], equal(babs, 2));
|
||||
cmov(t, &base[pos][2], equal(babs, 3));
|
||||
cmov(t, &base[pos][3], equal(babs, 4));
|
||||
cmov(t, &base[pos][4], equal(babs, 5));
|
||||
cmov(t, &base[pos][5], equal(babs, 6));
|
||||
cmov(t, &base[pos][6], equal(babs, 7));
|
||||
cmov(t, &base[pos][7], equal(babs, 8));
|
||||
fe_copy(minust.yplusx, t->yminusx);
|
||||
fe_copy(minust.yminusx, t->yplusx);
|
||||
fe_neg(minust.xy2d, t->xy2d);
|
||||
cmov(t, &minust, bnegative);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -384,53 +384,53 @@ Preconditions:
|
|||
*/
|
||||
|
||||
void ge_scalarmult_base(ge_p3 *h, const unsigned char *a) {
|
||||
signed char e[64];
|
||||
signed char carry;
|
||||
ge_p1p1 r;
|
||||
ge_p2 s;
|
||||
ge_precomp t;
|
||||
int i;
|
||||
signed char e[64];
|
||||
signed char carry;
|
||||
ge_p1p1 r;
|
||||
ge_p2 s;
|
||||
ge_precomp t;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 32; ++i) {
|
||||
e[2 * i + 0] = (a[i] >> 0) & 15;
|
||||
e[2 * i + 1] = (a[i] >> 4) & 15;
|
||||
}
|
||||
for(i = 0; i < 32; ++i) {
|
||||
e[2 * i + 0] = (a[i] >> 0) & 15;
|
||||
e[2 * i + 1] = (a[i] >> 4) & 15;
|
||||
}
|
||||
|
||||
/* each e[i] is between 0 and 15 */
|
||||
/* e[63] is between 0 and 7 */
|
||||
carry = 0;
|
||||
/* each e[i] is between 0 and 15 */
|
||||
/* e[63] is between 0 and 7 */
|
||||
carry = 0;
|
||||
|
||||
for (i = 0; i < 63; ++i) {
|
||||
e[i] += carry;
|
||||
carry = e[i] + 8;
|
||||
carry >>= 4;
|
||||
e[i] -= shl32(carry, 4);
|
||||
}
|
||||
for(i = 0; i < 63; ++i) {
|
||||
e[i] += carry;
|
||||
carry = e[i] + 8;
|
||||
carry >>= 4;
|
||||
e[i] -= shl32(carry, 4);
|
||||
}
|
||||
|
||||
e[63] += carry;
|
||||
/* each e[i] is between -8 and 8 */
|
||||
ge_p3_0(h);
|
||||
e[63] += carry;
|
||||
/* each e[i] is between -8 and 8 */
|
||||
ge_p3_0(h);
|
||||
|
||||
for (i = 1; i < 64; i += 2) {
|
||||
select(&t, i / 2, e[i]);
|
||||
ge_madd(&r, h, &t);
|
||||
ge_p1p1_to_p3(h, &r);
|
||||
}
|
||||
for(i = 1; i < 64; i += 2) {
|
||||
select(&t, i / 2, e[i]);
|
||||
ge_madd(&r, h, &t);
|
||||
ge_p1p1_to_p3(h, &r);
|
||||
}
|
||||
|
||||
ge_p3_dbl(&r, h);
|
||||
ge_p1p1_to_p2(&s, &r);
|
||||
ge_p2_dbl(&r, &s);
|
||||
ge_p1p1_to_p2(&s, &r);
|
||||
ge_p2_dbl(&r, &s);
|
||||
ge_p1p1_to_p2(&s, &r);
|
||||
ge_p2_dbl(&r, &s);
|
||||
ge_p1p1_to_p3(h, &r);
|
||||
ge_p3_dbl(&r, h);
|
||||
ge_p1p1_to_p2(&s, &r);
|
||||
ge_p2_dbl(&r, &s);
|
||||
ge_p1p1_to_p2(&s, &r);
|
||||
ge_p2_dbl(&r, &s);
|
||||
ge_p1p1_to_p2(&s, &r);
|
||||
ge_p2_dbl(&r, &s);
|
||||
ge_p1p1_to_p3(h, &r);
|
||||
|
||||
for (i = 0; i < 64; i += 2) {
|
||||
select(&t, i / 2, e[i]);
|
||||
ge_madd(&r, h, &t);
|
||||
ge_p1p1_to_p3(h, &r);
|
||||
}
|
||||
for(i = 0; i < 64; i += 2) {
|
||||
select(&t, i / 2, e[i]);
|
||||
ge_madd(&r, h, &t);
|
||||
ge_p1p1_to_p3(h, &r);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -439,29 +439,29 @@ r = p - q
|
|||
*/
|
||||
|
||||
void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
|
||||
fe t0;
|
||||
|
||||
fe_add(r->X, p->Y, p->X);
|
||||
fe_sub(r->Y, p->Y, p->X);
|
||||
fe_mul(r->Z, r->X, q->YminusX);
|
||||
fe_mul(r->Y, r->Y, q->YplusX);
|
||||
fe_mul(r->T, q->T2d, p->T);
|
||||
fe_mul(r->X, p->Z, q->Z);
|
||||
fe_add(t0, r->X, r->X);
|
||||
fe_sub(r->X, r->Z, r->Y);
|
||||
fe_add(r->Y, r->Z, r->Y);
|
||||
fe_sub(r->Z, t0, r->T);
|
||||
fe_add(r->T, t0, r->T);
|
||||
fe t0;
|
||||
|
||||
fe_add(r->X, p->Y, p->X);
|
||||
fe_sub(r->Y, p->Y, p->X);
|
||||
fe_mul(r->Z, r->X, q->YminusX);
|
||||
fe_mul(r->Y, r->Y, q->YplusX);
|
||||
fe_mul(r->T, q->T2d, p->T);
|
||||
fe_mul(r->X, p->Z, q->Z);
|
||||
fe_add(t0, r->X, r->X);
|
||||
fe_sub(r->X, r->Z, r->Y);
|
||||
fe_add(r->Y, r->Z, r->Y);
|
||||
fe_sub(r->Z, t0, r->T);
|
||||
fe_add(r->T, t0, r->T);
|
||||
}
|
||||
|
||||
|
||||
void ge_tobytes(unsigned char *s, const ge_p2 *h) {
|
||||
fe recip;
|
||||
fe x;
|
||||
fe y;
|
||||
fe_invert(recip, h->Z);
|
||||
fe_mul(x, h->X, recip);
|
||||
fe_mul(y, h->Y, recip);
|
||||
fe_tobytes(s, y);
|
||||
s[31] ^= fe_isnegative(x) << 7;
|
||||
fe recip;
|
||||
fe x;
|
||||
fe y;
|
||||
fe_invert(recip, h->Z);
|
||||
fe_mul(x, h->X, recip);
|
||||
fe_mul(y, h->Y, recip);
|
||||
fe_tobytes(s, y);
|
||||
s[31] ^= fe_isnegative(x) << 7;
|
||||
}
|
||||
|
|
|
@ -19,36 +19,36 @@ Representations:
|
|||
*/
|
||||
|
||||
typedef struct {
|
||||
fe X;
|
||||
fe Y;
|
||||
fe Z;
|
||||
fe X;
|
||||
fe Y;
|
||||
fe Z;
|
||||
} ge_p2;
|
||||
|
||||
typedef struct {
|
||||
fe X;
|
||||
fe Y;
|
||||
fe Z;
|
||||
fe T;
|
||||
fe X;
|
||||
fe Y;
|
||||
fe Z;
|
||||
fe T;
|
||||
} ge_p3;
|
||||
|
||||
typedef struct {
|
||||
fe X;
|
||||
fe Y;
|
||||
fe Z;
|
||||
fe T;
|
||||
fe X;
|
||||
fe Y;
|
||||
fe Z;
|
||||
fe T;
|
||||
} ge_p1p1;
|
||||
|
||||
typedef struct {
|
||||
fe yplusx;
|
||||
fe yminusx;
|
||||
fe xy2d;
|
||||
fe yplusx;
|
||||
fe yminusx;
|
||||
fe xy2d;
|
||||
} ge_precomp;
|
||||
|
||||
typedef struct {
|
||||
fe YplusX;
|
||||
fe YminusX;
|
||||
fe Z;
|
||||
fe T2d;
|
||||
fe YplusX;
|
||||
fe YminusX;
|
||||
fe Z;
|
||||
fe T2d;
|
||||
} ge_cached;
|
||||
|
||||
void ge_p3_tobytes(unsigned char *s, const ge_p3 *h);
|
||||
|
|
|
@ -2,78 +2,79 @@
|
|||
#include "fe.h"
|
||||
|
||||
void ed25519_key_exchange(unsigned char *shared_secret, const unsigned char *public_key, const unsigned char *private_key) {
|
||||
unsigned char e[32];
|
||||
unsigned int i;
|
||||
|
||||
fe x1;
|
||||
fe x2;
|
||||
fe z2;
|
||||
fe x3;
|
||||
fe z3;
|
||||
fe tmp0;
|
||||
fe tmp1;
|
||||
unsigned char e[32];
|
||||
unsigned int i;
|
||||
|
||||
int pos;
|
||||
unsigned int swap;
|
||||
unsigned int b;
|
||||
fe x1;
|
||||
fe x2;
|
||||
fe z2;
|
||||
fe x3;
|
||||
fe z3;
|
||||
fe tmp0;
|
||||
fe tmp1;
|
||||
|
||||
/* copy the private key and make sure it's valid */
|
||||
for (i = 0; i < 32; ++i) {
|
||||
e[i] = private_key[i];
|
||||
}
|
||||
int pos;
|
||||
unsigned int swap;
|
||||
unsigned int b;
|
||||
|
||||
e[0] &= 248;
|
||||
e[31] &= 63;
|
||||
e[31] |= 64;
|
||||
/* copy the private key and make sure it's valid */
|
||||
for(i = 0; i < 32; ++i) {
|
||||
e[i] = private_key[i];
|
||||
}
|
||||
|
||||
/* unpack the public key and convert edwards to montgomery */
|
||||
/* due to CodesInChaos: montgomeryX = (edwardsY + 1)*inverse(1 - edwardsY) mod p */
|
||||
fe_frombytes(x1, public_key);
|
||||
fe_1(tmp1);
|
||||
fe_add(tmp0, x1, tmp1);
|
||||
fe_sub(tmp1, tmp1, x1);
|
||||
fe_invert(tmp1, tmp1);
|
||||
fe_mul(x1, tmp0, tmp1);
|
||||
e[0] &= 248;
|
||||
e[31] &= 63;
|
||||
e[31] |= 64;
|
||||
|
||||
fe_1(x2);
|
||||
fe_0(z2);
|
||||
fe_copy(x3, x1);
|
||||
fe_1(z3);
|
||||
/* unpack the public key and convert edwards to montgomery */
|
||||
/* due to CodesInChaos: montgomeryX = (edwardsY + 1)*inverse(1 - edwardsY) mod p */
|
||||
fe_frombytes(x1, public_key);
|
||||
fe_1(tmp1);
|
||||
fe_add(tmp0, x1, tmp1);
|
||||
fe_sub(tmp1, tmp1, x1);
|
||||
fe_invert(tmp1, tmp1);
|
||||
fe_mul(x1, tmp0, tmp1);
|
||||
|
||||
swap = 0;
|
||||
for (pos = 254; pos >= 0; --pos) {
|
||||
b = e[pos / 8] >> (pos & 7);
|
||||
b &= 1;
|
||||
swap ^= b;
|
||||
fe_cswap(x2, x3, swap);
|
||||
fe_cswap(z2, z3, swap);
|
||||
swap = b;
|
||||
fe_1(x2);
|
||||
fe_0(z2);
|
||||
fe_copy(x3, x1);
|
||||
fe_1(z3);
|
||||
|
||||
/* from montgomery.h */
|
||||
fe_sub(tmp0, x3, z3);
|
||||
fe_sub(tmp1, x2, z2);
|
||||
fe_add(x2, x2, z2);
|
||||
fe_add(z2, x3, z3);
|
||||
fe_mul(z3, tmp0, x2);
|
||||
fe_mul(z2, z2, tmp1);
|
||||
fe_sq(tmp0, tmp1);
|
||||
fe_sq(tmp1, x2);
|
||||
fe_add(x3, z3, z2);
|
||||
fe_sub(z2, z3, z2);
|
||||
fe_mul(x2, tmp1, tmp0);
|
||||
fe_sub(tmp1, tmp1, tmp0);
|
||||
fe_sq(z2, z2);
|
||||
fe_mul121666(z3, tmp1);
|
||||
fe_sq(x3, x3);
|
||||
fe_add(tmp0, tmp0, z3);
|
||||
fe_mul(z3, x1, z2);
|
||||
fe_mul(z2, tmp1, tmp0);
|
||||
}
|
||||
swap = 0;
|
||||
|
||||
fe_cswap(x2, x3, swap);
|
||||
fe_cswap(z2, z3, swap);
|
||||
for(pos = 254; pos >= 0; --pos) {
|
||||
b = e[pos / 8] >> (pos & 7);
|
||||
b &= 1;
|
||||
swap ^= b;
|
||||
fe_cswap(x2, x3, swap);
|
||||
fe_cswap(z2, z3, swap);
|
||||
swap = b;
|
||||
|
||||
fe_invert(z2, z2);
|
||||
fe_mul(x2, x2, z2);
|
||||
fe_tobytes(shared_secret, x2);
|
||||
/* from montgomery.h */
|
||||
fe_sub(tmp0, x3, z3);
|
||||
fe_sub(tmp1, x2, z2);
|
||||
fe_add(x2, x2, z2);
|
||||
fe_add(z2, x3, z3);
|
||||
fe_mul(z3, tmp0, x2);
|
||||
fe_mul(z2, z2, tmp1);
|
||||
fe_sq(tmp0, tmp1);
|
||||
fe_sq(tmp1, x2);
|
||||
fe_add(x3, z3, z2);
|
||||
fe_sub(z2, z3, z2);
|
||||
fe_mul(x2, tmp1, tmp0);
|
||||
fe_sub(tmp1, tmp1, tmp0);
|
||||
fe_sq(z2, z2);
|
||||
fe_mul121666(z3, tmp1);
|
||||
fe_sq(x3, x3);
|
||||
fe_add(tmp0, tmp0, z3);
|
||||
fe_mul(z3, x1, z2);
|
||||
fe_mul(z2, tmp1, tmp0);
|
||||
}
|
||||
|
||||
fe_cswap(x2, x3, swap);
|
||||
fe_cswap(z2, z3, swap);
|
||||
|
||||
fe_invert(z2, z2);
|
||||
fe_mul(x2, x2, z2);
|
||||
fe_tobytes(shared_secret, x2);
|
||||
}
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
|
||||
|
||||
void ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, const unsigned char *seed) {
|
||||
ge_p3 A;
|
||||
ge_p3 A;
|
||||
|
||||
sha512(seed, 32, private_key);
|
||||
private_key[0] &= 248;
|
||||
private_key[31] &= 63;
|
||||
private_key[31] |= 64;
|
||||
sha512(seed, 32, private_key);
|
||||
private_key[0] &= 248;
|
||||
private_key[31] &= 63;
|
||||
private_key[31] |= 64;
|
||||
|
||||
ge_scalarmult_base(&A, private_key);
|
||||
ge_p3_tobytes(public_key, &A);
|
||||
ge_scalarmult_base(&A, private_key);
|
||||
ge_p3_tobytes(public_key, &A);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
1484
src/ed25519/sc.c
1484
src/ed25519/sc.c
File diff suppressed because it is too large
Load diff
|
@ -14,65 +14,65 @@
|
|||
|
||||
/* the K array */
|
||||
static const uint64_t K[80] = {
|
||||
UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd),
|
||||
UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc),
|
||||
UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019),
|
||||
UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118),
|
||||
UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe),
|
||||
UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2),
|
||||
UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1),
|
||||
UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694),
|
||||
UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3),
|
||||
UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65),
|
||||
UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483),
|
||||
UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5),
|
||||
UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210),
|
||||
UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4),
|
||||
UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725),
|
||||
UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70),
|
||||
UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926),
|
||||
UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df),
|
||||
UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8),
|
||||
UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b),
|
||||
UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001),
|
||||
UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30),
|
||||
UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910),
|
||||
UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8),
|
||||
UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53),
|
||||
UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8),
|
||||
UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb),
|
||||
UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3),
|
||||
UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60),
|
||||
UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec),
|
||||
UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9),
|
||||
UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b),
|
||||
UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207),
|
||||
UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178),
|
||||
UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6),
|
||||
UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b),
|
||||
UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493),
|
||||
UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c),
|
||||
UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a),
|
||||
UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817)
|
||||
UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd),
|
||||
UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc),
|
||||
UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019),
|
||||
UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118),
|
||||
UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe),
|
||||
UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2),
|
||||
UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1),
|
||||
UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694),
|
||||
UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3),
|
||||
UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65),
|
||||
UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483),
|
||||
UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5),
|
||||
UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210),
|
||||
UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4),
|
||||
UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725),
|
||||
UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70),
|
||||
UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926),
|
||||
UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df),
|
||||
UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8),
|
||||
UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b),
|
||||
UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001),
|
||||
UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30),
|
||||
UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910),
|
||||
UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8),
|
||||
UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53),
|
||||
UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8),
|
||||
UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb),
|
||||
UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3),
|
||||
UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60),
|
||||
UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec),
|
||||
UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9),
|
||||
UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b),
|
||||
UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207),
|
||||
UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178),
|
||||
UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6),
|
||||
UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b),
|
||||
UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493),
|
||||
UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c),
|
||||
UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a),
|
||||
UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817)
|
||||
};
|
||||
|
||||
/* Various logical functions */
|
||||
|
||||
#define ROR64c(x, y) \
|
||||
( ((((x)&UINT64_C(0xFFFFFFFFFFFFFFFF))>>((uint64_t)(y)&UINT64_C(63))) | \
|
||||
((x)<<((uint64_t)(64-((y)&UINT64_C(63)))))) & UINT64_C(0xFFFFFFFFFFFFFFFF))
|
||||
( ((((x)&UINT64_C(0xFFFFFFFFFFFFFFFF))>>((uint64_t)(y)&UINT64_C(63))) | \
|
||||
((x)<<((uint64_t)(64-((y)&UINT64_C(63)))))) & UINT64_C(0xFFFFFFFFFFFFFFFF))
|
||||
|
||||
#define STORE64H(x, y) \
|
||||
{ (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
|
||||
(y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
|
||||
(y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
|
||||
(y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
|
||||
{ (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
|
||||
(y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
|
||||
(y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
|
||||
(y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
|
||||
|
||||
#define LOAD64H(x, y) \
|
||||
{ x = (((uint64_t)((y)[0] & 255))<<56)|(((uint64_t)((y)[1] & 255))<<48) | \
|
||||
(((uint64_t)((y)[2] & 255))<<40)|(((uint64_t)((y)[3] & 255))<<32) | \
|
||||
(((uint64_t)((y)[4] & 255))<<24)|(((uint64_t)((y)[5] & 255))<<16) | \
|
||||
(((uint64_t)((y)[6] & 255))<<8)|(((uint64_t)((y)[7] & 255))); }
|
||||
{ x = (((uint64_t)((y)[0] & 255))<<56)|(((uint64_t)((y)[1] & 255))<<48) | \
|
||||
(((uint64_t)((y)[2] & 255))<<40)|(((uint64_t)((y)[3] & 255))<<32) | \
|
||||
(((uint64_t)((y)[4] & 255))<<24)|(((uint64_t)((y)[5] & 255))<<16) | \
|
||||
(((uint64_t)((y)[6] & 255))<<8)|(((uint64_t)((y)[7] & 255))); }
|
||||
|
||||
|
||||
#define Ch(x,y,z) (z ^ (x & (y ^ z)))
|
||||
|
@ -84,58 +84,57 @@ static const uint64_t K[80] = {
|
|||
#define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7))
|
||||
#define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6))
|
||||
#ifndef MIN
|
||||
#define MIN(x, y) ( ((x)<(y))?(x):(y) )
|
||||
#define MIN(x, y) ( ((x)<(y))?(x):(y) )
|
||||
#endif
|
||||
|
||||
/* compress 1024-bits */
|
||||
static int sha512_compress(sha512_context *md, const unsigned char *buf)
|
||||
{
|
||||
uint64_t S[8], W[80], t0, t1;
|
||||
int i;
|
||||
static int sha512_compress(sha512_context *md, const unsigned char *buf) {
|
||||
uint64_t S[8], W[80], t0, t1;
|
||||
int i;
|
||||
|
||||
/* copy state into S */
|
||||
for (i = 0; i < 8; i++) {
|
||||
S[i] = md->state[i];
|
||||
}
|
||||
/* copy state into S */
|
||||
for(i = 0; i < 8; i++) {
|
||||
S[i] = md->state[i];
|
||||
}
|
||||
|
||||
/* copy the state into 1024-bits into W[0..15] */
|
||||
for (i = 0; i < 16; i++) {
|
||||
LOAD64H(W[i], buf + (8*i));
|
||||
}
|
||||
/* copy the state into 1024-bits into W[0..15] */
|
||||
for(i = 0; i < 16; i++) {
|
||||
LOAD64H(W[i], buf + (8 * i));
|
||||
}
|
||||
|
||||
/* fill W[16..79] */
|
||||
for (i = 16; i < 80; i++) {
|
||||
W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
|
||||
}
|
||||
/* fill W[16..79] */
|
||||
for(i = 16; i < 80; i++) {
|
||||
W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
|
||||
}
|
||||
|
||||
/* Compress */
|
||||
#define RND(a,b,c,d,e,f,g,h,i) \
|
||||
t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
|
||||
t1 = Sigma0(a) + Maj(a, b, c);\
|
||||
d += t0; \
|
||||
h = t0 + t1;
|
||||
/* Compress */
|
||||
#define RND(a,b,c,d,e,f,g,h,i) \
|
||||
t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
|
||||
t1 = Sigma0(a) + Maj(a, b, c);\
|
||||
d += t0; \
|
||||
h = t0 + t1;
|
||||
|
||||
for (i = 0; i < 80; i += 8) {
|
||||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0);
|
||||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1);
|
||||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2);
|
||||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3);
|
||||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4);
|
||||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5);
|
||||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6);
|
||||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7);
|
||||
}
|
||||
for(i = 0; i < 80; i += 8) {
|
||||
RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i + 0);
|
||||
RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], i + 1);
|
||||
RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], i + 2);
|
||||
RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], i + 3);
|
||||
RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], i + 4);
|
||||
RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], i + 5);
|
||||
RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], i + 6);
|
||||
RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], i + 7);
|
||||
}
|
||||
|
||||
#undef RND
|
||||
#undef RND
|
||||
|
||||
|
||||
|
||||
/* feedback */
|
||||
for (i = 0; i < 8; i++) {
|
||||
md->state[i] = md->state[i] + S[i];
|
||||
}
|
||||
/* feedback */
|
||||
for(i = 0; i < 8; i++) {
|
||||
md->state[i] = md->state[i] + S[i];
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -144,21 +143,23 @@ static int sha512_compress(sha512_context *md, const unsigned char *buf)
|
|||
@param md The hash state you wish to initialize
|
||||
@return 0 if successful
|
||||
*/
|
||||
int sha512_init(sha512_context * md) {
|
||||
if (md == NULL) return 1;
|
||||
int sha512_init(sha512_context *md) {
|
||||
if(md == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
md->curlen = 0;
|
||||
md->length = 0;
|
||||
md->state[0] = UINT64_C(0x6a09e667f3bcc908);
|
||||
md->state[1] = UINT64_C(0xbb67ae8584caa73b);
|
||||
md->state[2] = UINT64_C(0x3c6ef372fe94f82b);
|
||||
md->state[3] = UINT64_C(0xa54ff53a5f1d36f1);
|
||||
md->state[4] = UINT64_C(0x510e527fade682d1);
|
||||
md->state[5] = UINT64_C(0x9b05688c2b3e6c1f);
|
||||
md->state[6] = UINT64_C(0x1f83d9abfb41bd6b);
|
||||
md->state[7] = UINT64_C(0x5be0cd19137e2179);
|
||||
md->curlen = 0;
|
||||
md->length = 0;
|
||||
md->state[0] = UINT64_C(0x6a09e667f3bcc908);
|
||||
md->state[1] = UINT64_C(0xbb67ae8584caa73b);
|
||||
md->state[2] = UINT64_C(0x3c6ef372fe94f82b);
|
||||
md->state[3] = UINT64_C(0xa54ff53a5f1d36f1);
|
||||
md->state[4] = UINT64_C(0x510e527fade682d1);
|
||||
md->state[5] = UINT64_C(0x9b05688c2b3e6c1f);
|
||||
md->state[6] = UINT64_C(0x1f83d9abfb41bd6b);
|
||||
md->state[7] = UINT64_C(0x5be0cd19137e2179);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -168,46 +169,57 @@ 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)
|
||||
{
|
||||
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->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;
|
||||
} else {
|
||||
n = MIN(inlen, (128 - md->curlen));
|
||||
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;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
md->buf[i + md->curlen] = in[i];
|
||||
}
|
||||
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;
|
||||
} else {
|
||||
n = MIN(inlen, (128 - md->curlen));
|
||||
|
||||
for(i = 0; i < n; i++) {
|
||||
md->buf[i + md->curlen] = in[i];
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
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,62 +228,76 @@ 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 i;
|
||||
unsigned char *out = 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 (md->curlen >= sizeof(md->buf)) {
|
||||
return 1;
|
||||
}
|
||||
if(out == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* increase the length of the message */
|
||||
md->length += md->curlen * UINT64_C(8);
|
||||
if(md->curlen >= sizeof(md->buf)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* append the '1' bit */
|
||||
md->buf[md->curlen++] = (unsigned char)0x80;
|
||||
/* increase the length of the message */
|
||||
md->length += md->curlen * UINT64_C(8);
|
||||
|
||||
/* if the length is currently above 112 bytes we append zeros
|
||||
* then compress. Then we can fall back to padding zeros and length
|
||||
* encoding like normal.
|
||||
*/
|
||||
if (md->curlen > 112) {
|
||||
while (md->curlen < 128) {
|
||||
md->buf[md->curlen++] = (unsigned char)0;
|
||||
}
|
||||
sha512_compress(md, md->buf);
|
||||
md->curlen = 0;
|
||||
}
|
||||
/* append the '1' bit */
|
||||
md->buf[md->curlen++] = (unsigned char)0x80;
|
||||
|
||||
/* pad upto 120 bytes of zeroes
|
||||
* note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash
|
||||
* > 2^64 bits of data... :-)
|
||||
*/
|
||||
while (md->curlen < 120) {
|
||||
md->buf[md->curlen++] = (unsigned char)0;
|
||||
}
|
||||
/* if the length is currently above 112 bytes we append zeros
|
||||
* then compress. Then we can fall back to padding zeros and length
|
||||
* encoding like normal.
|
||||
*/
|
||||
if(md->curlen > 112) {
|
||||
while(md->curlen < 128) {
|
||||
md->buf[md->curlen++] = (unsigned char)0;
|
||||
}
|
||||
|
||||
/* store length */
|
||||
STORE64H(md->length, md->buf+120);
|
||||
sha512_compress(md, md->buf);
|
||||
sha512_compress(md, md->buf);
|
||||
md->curlen = 0;
|
||||
}
|
||||
|
||||
/* copy output */
|
||||
for (i = 0; i < 8; i++) {
|
||||
STORE64H(md->state[i], out+(8*i));
|
||||
}
|
||||
/* pad up to 120 bytes of zeroes
|
||||
* note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash
|
||||
* > 2^64 bits of data... :-)
|
||||
*/
|
||||
while(md->curlen < 120) {
|
||||
md->buf[md->curlen++] = (unsigned char)0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
/* store length */
|
||||
STORE64H(md->length, md->buf + 120);
|
||||
sha512_compress(md, md->buf);
|
||||
|
||||
/* copy output */
|
||||
for(i = 0; i < 8; i++) {
|
||||
STORE64H(md->state[i], out + (8 * i));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
return 0;
|
||||
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;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -7,15 +7,15 @@
|
|||
|
||||
/* state */
|
||||
typedef struct sha512_context_ {
|
||||
uint64_t length, state[8];
|
||||
size_t curlen;
|
||||
unsigned char buf[128];
|
||||
uint64_t length, state[8];
|
||||
size_t curlen;
|
||||
unsigned char buf[128];
|
||||
} sha512_context;
|
||||
|
||||
|
||||
int sha512_init(sha512_context * md);
|
||||
int sha512_final(sha512_context * md, void *out);
|
||||
int sha512_update(sha512_context * md, const void *in, size_t inlen);
|
||||
int sha512_init(sha512_context *md);
|
||||
int sha512_final(sha512_context *md, void *out);
|
||||
int sha512_update(sha512_context *md, const void *in, size_t inlen);
|
||||
int sha512(const void *message, size_t message_len, void *out);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,27 +5,27 @@
|
|||
|
||||
|
||||
void ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key, const unsigned char *private_key) {
|
||||
sha512_context hash;
|
||||
unsigned char hram[64];
|
||||
unsigned char r[64];
|
||||
ge_p3 R;
|
||||
sha512_context hash;
|
||||
unsigned char hram[64];
|
||||
unsigned char r[64];
|
||||
ge_p3 R;
|
||||
|
||||
|
||||
sha512_init(&hash);
|
||||
sha512_update(&hash, private_key + 32, 32);
|
||||
sha512_update(&hash, message, message_len);
|
||||
sha512_final(&hash, r);
|
||||
sha512_init(&hash);
|
||||
sha512_update(&hash, private_key + 32, 32);
|
||||
sha512_update(&hash, message, message_len);
|
||||
sha512_final(&hash, r);
|
||||
|
||||
sc_reduce(r);
|
||||
ge_scalarmult_base(&R, r);
|
||||
ge_p3_tobytes(signature, &R);
|
||||
sc_reduce(r);
|
||||
ge_scalarmult_base(&R, r);
|
||||
ge_p3_tobytes(signature, &R);
|
||||
|
||||
sha512_init(&hash);
|
||||
sha512_update(&hash, signature, 32);
|
||||
sha512_update(&hash, public_key, 32);
|
||||
sha512_update(&hash, message, message_len);
|
||||
sha512_final(&hash, hram);
|
||||
sha512_init(&hash);
|
||||
sha512_update(&hash, signature, 32);
|
||||
sha512_update(&hash, public_key, 32);
|
||||
sha512_update(&hash, message, message_len);
|
||||
sha512_final(&hash, hram);
|
||||
|
||||
sc_reduce(hram);
|
||||
sc_muladd(signature + 32, hram, private_key, r);
|
||||
sc_reduce(hram);
|
||||
sc_muladd(signature + 32, hram, private_key, r);
|
||||
}
|
||||
|
|
|
@ -4,74 +4,74 @@
|
|||
#include "sc.h"
|
||||
|
||||
static int consttime_equal(const unsigned char *x, const unsigned char *y) {
|
||||
unsigned char r = 0;
|
||||
unsigned char r = 0;
|
||||
|
||||
r = x[0] ^ y[0];
|
||||
#define F(i) r |= x[i] ^ y[i]
|
||||
F(1);
|
||||
F(2);
|
||||
F(3);
|
||||
F(4);
|
||||
F(5);
|
||||
F(6);
|
||||
F(7);
|
||||
F(8);
|
||||
F(9);
|
||||
F(10);
|
||||
F(11);
|
||||
F(12);
|
||||
F(13);
|
||||
F(14);
|
||||
F(15);
|
||||
F(16);
|
||||
F(17);
|
||||
F(18);
|
||||
F(19);
|
||||
F(20);
|
||||
F(21);
|
||||
F(22);
|
||||
F(23);
|
||||
F(24);
|
||||
F(25);
|
||||
F(26);
|
||||
F(27);
|
||||
F(28);
|
||||
F(29);
|
||||
F(30);
|
||||
F(31);
|
||||
#undef F
|
||||
r = x[0] ^ y[0];
|
||||
#define F(i) r |= x[i] ^ y[i]
|
||||
F(1);
|
||||
F(2);
|
||||
F(3);
|
||||
F(4);
|
||||
F(5);
|
||||
F(6);
|
||||
F(7);
|
||||
F(8);
|
||||
F(9);
|
||||
F(10);
|
||||
F(11);
|
||||
F(12);
|
||||
F(13);
|
||||
F(14);
|
||||
F(15);
|
||||
F(16);
|
||||
F(17);
|
||||
F(18);
|
||||
F(19);
|
||||
F(20);
|
||||
F(21);
|
||||
F(22);
|
||||
F(23);
|
||||
F(24);
|
||||
F(25);
|
||||
F(26);
|
||||
F(27);
|
||||
F(28);
|
||||
F(29);
|
||||
F(30);
|
||||
F(31);
|
||||
#undef F
|
||||
|
||||
return !r;
|
||||
return !r;
|
||||
}
|
||||
|
||||
int ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key) {
|
||||
unsigned char h[64];
|
||||
unsigned char checker[32];
|
||||
sha512_context hash;
|
||||
ge_p3 A;
|
||||
ge_p2 R;
|
||||
unsigned char h[64];
|
||||
unsigned char checker[32];
|
||||
sha512_context hash;
|
||||
ge_p3 A;
|
||||
ge_p2 R;
|
||||
|
||||
if (signature[63] & 224) {
|
||||
return 0;
|
||||
}
|
||||
if(signature[63] & 224) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ge_frombytes_negate_vartime(&A, public_key) != 0) {
|
||||
return 0;
|
||||
}
|
||||
if(ge_frombytes_negate_vartime(&A, public_key) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
sha512_init(&hash);
|
||||
sha512_update(&hash, signature, 32);
|
||||
sha512_update(&hash, public_key, 32);
|
||||
sha512_update(&hash, message, message_len);
|
||||
sha512_final(&hash, h);
|
||||
|
||||
sc_reduce(h);
|
||||
ge_double_scalarmult_vartime(&R, h, &A, signature + 32);
|
||||
ge_tobytes(checker, &R);
|
||||
sha512_init(&hash);
|
||||
sha512_update(&hash, signature, 32);
|
||||
sha512_update(&hash, public_key, 32);
|
||||
sha512_update(&hash, message, message_len);
|
||||
sha512_final(&hash, h);
|
||||
|
||||
if (!consttime_equal(checker, signature)) {
|
||||
return 0;
|
||||
}
|
||||
sc_reduce(h);
|
||||
ge_double_scalarmult_vartime(&R, h, &A, signature + 32);
|
||||
ge_tobytes(checker, &R);
|
||||
|
||||
return 1;
|
||||
if(!consttime_equal(checker, signature)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
20
src/edge.c
20
src/edge.c
|
@ -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);
|
||||
|
@ -111,11 +115,11 @@ bool dump_edges(connection_t *c) {
|
|||
for splay_each(node_t, n, node_tree) {
|
||||
for splay_each(edge_t, e, n->edge_tree) {
|
||||
char *address = sockaddr2hostname(&e->address);
|
||||
char* local_address = sockaddr2hostname(&e->local_address);
|
||||
char *local_address = sockaddr2hostname(&e->local_address);
|
||||
send_request(c, "%d %d %s %s %s %s %x %d",
|
||||
CONTROL, REQ_DUMP_EDGES,
|
||||
e->from->name, e->to->name, address,
|
||||
local_address, e->options, e->weight);
|
||||
CONTROL, REQ_DUMP_EDGES,
|
||||
e->from->name, e->to->name, address,
|
||||
local_address, e->options, e->weight);
|
||||
free(address);
|
||||
free(local_address);
|
||||
}
|
||||
|
|
24
src/edge.h
24
src/edge.h
|
@ -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"
|
||||
|
@ -43,13 +43,13 @@ 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 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 edge_t *new_edge(void) __attribute__((__malloc__));
|
||||
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 *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
|
||||
|
|
|
@ -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
|
||||
|
@ -63,7 +63,7 @@ struct ether_header {
|
|||
uint8_t ether_dhost[ETH_ALEN];
|
||||
uint8_t ether_shost[ETH_ALEN];
|
||||
uint16_t ether_type;
|
||||
} __attribute__ ((__gcc_struct__, __packed__));
|
||||
} __attribute__((__gcc_struct__, __packed__));
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_ARPHDR
|
||||
|
@ -73,7 +73,7 @@ struct arphdr {
|
|||
uint8_t ar_hln;
|
||||
uint8_t ar_pln;
|
||||
uint16_t ar_op;
|
||||
} __attribute__ ((__gcc_struct__, __packed__));
|
||||
} __attribute__((__gcc_struct__, __packed__));
|
||||
|
||||
#define ARPOP_REQUEST 1
|
||||
#define ARPOP_REPLY 2
|
||||
|
@ -91,7 +91,7 @@ struct ether_arp {
|
|||
uint8_t arp_spa[4];
|
||||
uint8_t arp_tha[ETH_ALEN];
|
||||
uint8_t arp_tpa[4];
|
||||
} __attribute__ ((__gcc_struct__, __packed__));
|
||||
} __attribute__((__gcc_struct__, __packed__));
|
||||
#define arp_hrd ea_hdr.ar_hrd
|
||||
#define arp_pro ea_hdr.ar_pro
|
||||
#define arp_hln ea_hdr.ar_hln
|
||||
|
@ -99,4 +99,4 @@ struct ether_arp {
|
|||
#define arp_op ea_hdr.ar_op
|
||||
#endif
|
||||
|
||||
#endif /* __TINC_ETHERNET_H__ */
|
||||
#endif
|
||||
|
|
287
src/event.c
287
src/event.c
|
@ -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) {
|
||||
|
||||
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,8 +112,9 @@ 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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -227,7 +293,7 @@ void signal_del(signal_t *sig) {
|
|||
}
|
||||
#endif
|
||||
|
||||
static struct timeval * get_time_remaining(struct timeval *diff) {
|
||||
static struct timeval *get_time_remaining(struct timeval *diff) {
|
||||
gettimeofday(&now, NULL);
|
||||
struct timeval *tv = NULL;
|
||||
|
||||
|
@ -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,39 +339,48 @@ 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.
|
||||
*/
|
||||
break;
|
||||
if(curgen != io_tree.generation) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
while (running) {
|
||||
|
||||
while(running) {
|
||||
struct timeval diff;
|
||||
struct timeval *tv = get_time_remaining(&diff);
|
||||
DWORD timeout_ms = tv ? (tv->tv_sec * 1000 + tv->tv_usec / 1000 + 1) : WSA_INFINITE;
|
||||
|
||||
if (!event_count) {
|
||||
if(!event_count) {
|
||||
Sleep(timeout_ms);
|
||||
continue;
|
||||
}
|
||||
|
@ -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)
|
||||
if (io->flags & IO_WRITE && send(io->fd, NULL, 0, 0) == 0) {
|
||||
writeable_io = io;
|
||||
break;
|
||||
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) {
|
||||
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 (io->fd == -1) {
|
||||
io->cb(io->data, 0);
|
||||
} else {
|
||||
WSANETWORKEVENTS network_events;
|
||||
if (WSAEnumNetworkEvents(io->fd, io->event, &network_events) != 0)
|
||||
return false;
|
||||
if (network_events.lNetworkEvents & READ_EVENTS)
|
||||
io->cb(io->data, IO_READ);
|
||||
/*
|
||||
The fd might be available for write too. However, if we already fired the read callback, that
|
||||
callback might have deleted the io (e.g. through terminate_connection()), so we can't fire the
|
||||
write callback here. Instead, we loop back and let the writable io loop above handle it.
|
||||
*/
|
||||
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) {
|
||||
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;
|
||||
|
|
|
@ -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
|
||||
|
@ -58,7 +58,7 @@ extern struct timeval now;
|
|||
|
||||
extern void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags);
|
||||
#ifdef HAVE_MINGW
|
||||
extern void io_add_event(io_t *io, io_cb_t cb, void* data, WSAEVENT event);
|
||||
extern void io_add_event(io_t *io, io_cb_t cb, void *data, WSAEVENT event);
|
||||
#endif
|
||||
extern void io_del(io_t *io);
|
||||
extern void io_set(io_t *io, int flags);
|
||||
|
|
|
@ -64,7 +64,7 @@ static void close_device(void) {
|
|||
}
|
||||
|
||||
static inline uint16_t get_ip_ethertype(vpn_packet_t *packet) {
|
||||
switch (DATA(packet)[ETH_HLEN] >> 4) {
|
||||
switch(DATA(packet)[ETH_HLEN] >> 4) {
|
||||
case 4:
|
||||
return ETH_P_IP;
|
||||
|
||||
|
@ -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;
|
||||
|
|
218
src/fsck.c
218
src/fsck.c
|
@ -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,119 +451,150 @@ 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.
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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,10 +146,8 @@ void cipher_close(cipher_t *cipher) {
|
|||
cipher->handle = NULL;
|
||||
}
|
||||
|
||||
if(cipher->key) {
|
||||
free(cipher->key);
|
||||
cipher->key = NULL;
|
||||
}
|
||||
free(cipher->key);
|
||||
cipher->key = NULL;
|
||||
}
|
||||
|
||||
size_t cipher_keylength(const cipher_t *cipher) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue