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.
|
See the AUTHORS file for a complete list.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
|
|
@ -2,12 +2,14 @@
|
||||||
|
|
||||||
AUTOMAKE_OPTIONS = gnu
|
AUTOMAKE_OPTIONS = gnu
|
||||||
|
|
||||||
SUBDIRS = src doc gui test systemd
|
SUBDIRS = src doc test systemd
|
||||||
|
|
||||||
ACLOCAL_AMFLAGS = -I m4
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
|
|
||||||
EXTRA_DIST = COPYING.README README.android
|
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
|
# 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.
|
# current version number from git in the resulting configure script.
|
||||||
configure-version:
|
configure-version:
|
||||||
|
@ -33,3 +35,6 @@ release:
|
||||||
echo "Please edit the NEWS file now..."
|
echo "Please edit the NEWS file now..."
|
||||||
/usr/bin/editor $(srcdir)/NEWS
|
/usr/bin/editor $(srcdir)/NEWS
|
||||||
$(MAKE) dist
|
$(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@
|
# @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
|
# This Makefile.in is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# 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_cflags_warn_all.m4 \
|
||||||
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
|
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
|
||||||
$(top_srcdir)/m4/ax_check_link_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/ax_require_defined.m4 \
|
||||||
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \
|
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \
|
||||||
$(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \
|
$(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \
|
||||||
|
@ -143,7 +144,7 @@ am__recursive_targets = \
|
||||||
$(RECURSIVE_CLEAN_TARGETS) \
|
$(RECURSIVE_CLEAN_TARGETS) \
|
||||||
$(am__extra_recursive_targets)
|
$(am__extra_recursive_targets)
|
||||||
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
|
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) \
|
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
|
||||||
$(LISP)config.h.in
|
$(LISP)config.h.in
|
||||||
# Read a list of newline-separated strings from the standard input,
|
# Read a list of newline-separated strings from the standard input,
|
||||||
|
@ -221,6 +222,12 @@ AWK = @AWK@
|
||||||
CC = @CC@
|
CC = @CC@
|
||||||
CCDEPMODE = @CCDEPMODE@
|
CCDEPMODE = @CCDEPMODE@
|
||||||
CFLAGS = @CFLAGS@
|
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@
|
CPP = @CPP@
|
||||||
CPPFLAGS = @CPPFLAGS@
|
CPPFLAGS = @CPPFLAGS@
|
||||||
CURSES_LIBS = @CURSES_LIBS@
|
CURSES_LIBS = @CURSES_LIBS@
|
||||||
|
@ -232,16 +239,18 @@ ECHO_N = @ECHO_N@
|
||||||
ECHO_T = @ECHO_T@
|
ECHO_T = @ECHO_T@
|
||||||
EGREP = @EGREP@
|
EGREP = @EGREP@
|
||||||
EXEEXT = @EXEEXT@
|
EXEEXT = @EXEEXT@
|
||||||
|
GCOV = @GCOV@
|
||||||
|
GENHTML = @GENHTML@
|
||||||
GREP = @GREP@
|
GREP = @GREP@
|
||||||
INSTALL = @INSTALL@
|
INSTALL = @INSTALL@
|
||||||
INSTALL_DATA = @INSTALL_DATA@
|
INSTALL_DATA = @INSTALL_DATA@
|
||||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||||
|
LCOV = @LCOV@
|
||||||
LDFLAGS = @LDFLAGS@
|
LDFLAGS = @LDFLAGS@
|
||||||
LIBOBJS = @LIBOBJS@
|
LIBOBJS = @LIBOBJS@
|
||||||
LIBS = @LIBS@
|
LIBS = @LIBS@
|
||||||
LN_S = @LN_S@
|
|
||||||
LTLIBOBJS = @LTLIBOBJS@
|
LTLIBOBJS = @LTLIBOBJS@
|
||||||
MAKEINFO = @MAKEINFO@
|
MAKEINFO = @MAKEINFO@
|
||||||
MINIUPNPC_LIBS = @MINIUPNPC_LIBS@
|
MINIUPNPC_LIBS = @MINIUPNPC_LIBS@
|
||||||
|
@ -256,6 +265,7 @@ PACKAGE_URL = @PACKAGE_URL@
|
||||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||||
READLINE_LIBS = @READLINE_LIBS@
|
READLINE_LIBS = @READLINE_LIBS@
|
||||||
|
SED = @SED@
|
||||||
SET_MAKE = @SET_MAKE@
|
SET_MAKE = @SET_MAKE@
|
||||||
SHELL = @SHELL@
|
SHELL = @SHELL@
|
||||||
STRIP = @STRIP@
|
STRIP = @STRIP@
|
||||||
|
@ -313,7 +323,7 @@ top_build_prefix = @top_build_prefix@
|
||||||
top_builddir = @top_builddir@
|
top_builddir = @top_builddir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
AUTOMAKE_OPTIONS = gnu
|
AUTOMAKE_OPTIONS = gnu
|
||||||
SUBDIRS = src doc gui test systemd
|
SUBDIRS = src doc test systemd
|
||||||
ACLOCAL_AMFLAGS = -I m4
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
EXTRA_DIST = COPYING.README README.android
|
EXTRA_DIST = COPYING.README README.android
|
||||||
all: config.h
|
all: config.h
|
||||||
|
@ -341,8 +351,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||||
echo ' $(SHELL) ./config.status'; \
|
echo ' $(SHELL) ./config.status'; \
|
||||||
$(SHELL) ./config.status;; \
|
$(SHELL) ./config.status;; \
|
||||||
*) \
|
*) \
|
||||||
echo ' 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__depfiles_maybe);; \
|
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \
|
||||||
esac;
|
esac;
|
||||||
|
|
||||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
$(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 TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||||
-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
|
-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)
|
$(am__remove_distdir)
|
||||||
test -d "$(distdir)" || mkdir "$(distdir)"
|
test -d "$(distdir)" || mkdir "$(distdir)"
|
||||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||||
|
@ -788,6 +801,8 @@ uninstall-am:
|
||||||
.PRECIOUS: Makefile
|
.PRECIOUS: Makefile
|
||||||
|
|
||||||
|
|
||||||
|
@CODE_COVERAGE_RULES@
|
||||||
|
|
||||||
# If git describe works, force autoconf to run in order to make sure we have the
|
# 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.
|
# current version number from git in the resulting configure script.
|
||||||
configure-version:
|
configure-version:
|
||||||
|
@ -814,6 +829,9 @@ release:
|
||||||
/usr/bin/editor $(srcdir)/NEWS
|
/usr/bin/editor $(srcdir)/NEWS
|
||||||
$(MAKE) dist
|
$(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.
|
# 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.
|
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||||
.NOEXPORT:
|
.NOEXPORT:
|
||||||
|
|
38
NEWS
38
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
|
# Version 1.1pre15 September 2 2017
|
||||||
|
|
||||||
* Detect when the machine is resuming from suspension or hibernation.
|
* Detect when the machine is resuming from suspension or hibernation.
|
||||||
|
@ -12,7 +44,7 @@
|
||||||
* Support PriorityInheritance for IPv6 packets.
|
* Support PriorityInheritance for IPv6 packets.
|
||||||
* Fixes for Solaris tun/tap support.
|
* Fixes for Solaris tun/tap support.
|
||||||
* Add a configurable expiration time for invitations.
|
* 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.
|
* Exit gracefully when the tun/tap device is in a bad state.
|
||||||
* Add the LogLevel option.
|
* Add the LogLevel option.
|
||||||
* AutoConnect now actively tries to heal split networks.
|
* 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
|
* Allow tinc to be compiled without LibreSSL or OpenSSL (this drops
|
||||||
compatibility with nodes running 1.0.x).
|
compatibility with nodes running 1.0.x).
|
||||||
* Added a "fsck" command to check the configuration files for problems.
|
* 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.
|
displays error messages otherwise.
|
||||||
* Added systemd service files.
|
* Added systemd service files.
|
||||||
* Use the recvmmsg() function if available.
|
* 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.
|
* Improved default settings of tun and tap devices on BSD platforms.
|
||||||
* Make IPv6 sockets bind only to IPv6 on Linux.
|
* Make IPv6 sockets bind only to IPv6 on Linux.
|
||||||
* Enable path MTU discovery by default.
|
* 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.
|
Thanks to Max Rijevski for his contributions to this version of tinc.
|
||||||
|
|
||||||
|
|
28
README
28
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.
|
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.
|
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
|
This version uses an experimental and unfinished cryptographic protocol. Use it
|
||||||
at your own risk.
|
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
|
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.
|
versions of tinc.
|
||||||
|
|
||||||
When the ExperimentalProtocol option is used, tinc is still compatible with
|
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:
|
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/)
|
- 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)
|
- 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
|
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
|
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
|
RSA keys for authentication, and encrypts traffic using AES256 in CBC mode
|
||||||
and HMAC-SHA1. The second is a new protocol which uses Curve25519 keys for
|
and HMAC-SHA256. The second is a new protocol which uses Curve25519 keys for
|
||||||
authentication, and encrypts traffic using Chacha20-Poly1305, and provides
|
authentication, and encrypts traffic using Chacha20-Poly1305, and provides
|
||||||
forward secrecy.
|
forward secrecy.
|
||||||
|
|
||||||
|
|
18
THANKS
18
THANKS
|
@ -5,9 +5,12 @@ We would like to thank the following people for their contributions to tinc:
|
||||||
* Alexis Hildebrandt
|
* Alexis Hildebrandt
|
||||||
* Allesandro Gatti
|
* Allesandro Gatti
|
||||||
* Andreas van Cranenburgh
|
* Andreas van Cranenburgh
|
||||||
|
* Andrew Hahn
|
||||||
* Anthony G. Basile
|
* Anthony G. Basile
|
||||||
* Armijn Hemel
|
* Armijn Hemel
|
||||||
* Armin Fisslthaler
|
* Armin Fisslthaler
|
||||||
|
* Aron Cowan
|
||||||
|
* Ashish Bajaj
|
||||||
* Baptiste Jonglez
|
* Baptiste Jonglez
|
||||||
* Borg
|
* Borg
|
||||||
* Brandon Black
|
* Brandon Black
|
||||||
|
@ -19,35 +22,41 @@ We would like to thank the following people for their contributions to tinc:
|
||||||
* Delf Eldkraft
|
* Delf Eldkraft
|
||||||
* Dennis Joachimsthaler
|
* Dennis Joachimsthaler
|
||||||
* dnk
|
* dnk
|
||||||
|
* Élie Bouttier
|
||||||
* Enrique Zanardi
|
* Enrique Zanardi
|
||||||
* Erik Tews
|
* Erik Tews
|
||||||
* Etienne Dechamps
|
* Etienne Dechamps
|
||||||
* Florent Clairambault
|
* Florent Clairambault
|
||||||
|
* Florian Forster
|
||||||
* Florian Klink
|
* Florian Klink
|
||||||
* Florian Weik
|
* Florian Weik
|
||||||
* Flynn Marquardt
|
* Flynn Marquardt
|
||||||
* Franz Pletz
|
* Franz Pletz
|
||||||
* Gary Kessler and Claudia Gonzalez
|
* Gary Kessler and Claudia Gonzalez
|
||||||
* Grzegorz Dymarek
|
* Grzegorz Dymarek
|
||||||
|
* Gusariev Oleksandr
|
||||||
* Hans Bayle
|
* Hans Bayle
|
||||||
* Harvest
|
* Harvest
|
||||||
|
* Ivo Smits
|
||||||
* Ivo van Dong
|
* Ivo van Dong
|
||||||
* James Cook
|
* James Cook
|
||||||
* James MacLean
|
* James MacLean
|
||||||
* Jamie Briggs
|
* Jamie Briggs
|
||||||
* Jason Harper
|
* Jason Harper
|
||||||
* Jason Livesay
|
* Jason Livesay
|
||||||
|
* Jasper Krijgsman
|
||||||
* Jelle de Jong
|
* Jelle de Jong
|
||||||
* Jeroen Domburg
|
* Jeroen Domburg
|
||||||
* Jeroen Ubbink
|
* Jeroen Ubbink
|
||||||
* Jerome Etienne
|
* Jerome Etienne
|
||||||
* Jo-Philipp Wich
|
|
||||||
* Jochen Voss
|
* Jochen Voss
|
||||||
|
* Jo-Philipp Wich
|
||||||
* Julien Muchembled
|
* Julien Muchembled
|
||||||
* Lavrans Laading
|
* Lavrans Laading
|
||||||
* Loïc Dachary
|
* Loïc Dachary
|
||||||
* Loïc Grenié
|
* Loïc Grenié
|
||||||
* Lubomír Bulej
|
* Lubomír Bulej
|
||||||
|
* luckyhacky
|
||||||
* LunarShaddow
|
* LunarShaddow
|
||||||
* Mads Kiilerich
|
* Mads Kiilerich
|
||||||
* Marc A. Lehmann
|
* Marc A. Lehmann
|
||||||
|
@ -63,18 +72,22 @@ We would like to thank the following people for their contributions to tinc:
|
||||||
* Menno Smits
|
* Menno Smits
|
||||||
* Mesar Hameed
|
* Mesar Hameed
|
||||||
* Michael Tokarev
|
* Michael Tokarev
|
||||||
|
* Michael Yonli
|
||||||
* Miles Nordin
|
* Miles Nordin
|
||||||
* Nathan Stratton Treadway
|
|
||||||
* Murat Donmez
|
* Murat Donmez
|
||||||
|
* Nathan Stratton Treadway
|
||||||
* Nick Hibma
|
* Nick Hibma
|
||||||
* Nick Patavalis
|
* Nick Patavalis
|
||||||
* Paul Littlefield
|
* Paul Littlefield
|
||||||
* Philipp Babel
|
* Philipp Babel
|
||||||
* Pierre Emeriaud
|
* Pierre Emeriaud
|
||||||
|
* Pierre-Olivier Mercier
|
||||||
|
* Rafael Sadowski
|
||||||
* Rafał Leśniak
|
* Rafał Leśniak
|
||||||
* Rhosyn Celyn
|
* Rhosyn Celyn
|
||||||
* Robert van der Meulen
|
* Robert van der Meulen
|
||||||
* Rumko
|
* Rumko
|
||||||
|
* Ryan Miller
|
||||||
* Sam Bryan
|
* Sam Bryan
|
||||||
* Samuel Thibault
|
* Samuel Thibault
|
||||||
* Saverio Proto
|
* Saverio Proto
|
||||||
|
@ -92,6 +105,7 @@ We would like to thank the following people for their contributions to tinc:
|
||||||
* Ulrich Seifert
|
* Ulrich Seifert
|
||||||
* Vil Brekin
|
* Vil Brekin
|
||||||
* Vittorio Gambaletta
|
* Vittorio Gambaletta
|
||||||
|
* Wendy Willard
|
||||||
* Wessel Dankers
|
* Wessel Dankers
|
||||||
* William A. Kennington III
|
* William A. Kennington III
|
||||||
* William McArthur
|
* William McArthur
|
||||||
|
|
188
aclocal.m4
vendored
188
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
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# 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.
|
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'.])])
|
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
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# 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.
|
# generated from the m4 files accompanying Automake X.Y.
|
||||||
# (This private macro should not be called outside this file.)
|
# (This private macro should not be called outside this file.)
|
||||||
AC_DEFUN([AM_AUTOMAKE_VERSION],
|
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 Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
|
||||||
dnl require some minimum version. Point them to the right macro.
|
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
|
[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.
|
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
|
||||||
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
|
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
|
||||||
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
|
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_ifndef([AC_AUTOCONF_VERSION],
|
||||||
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
|
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
|
||||||
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
|
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
|
||||||
|
|
||||||
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
|
# 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
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -110,7 +110,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd`
|
||||||
|
|
||||||
# AM_CONDITIONAL -*- Autoconf -*-
|
# 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
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# 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.]])
|
Usually this means the macro was only invoked conditionally.]])
|
||||||
fi])])
|
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
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# 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 -*-
|
# 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
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
# with or without modifications, as long as this notice is preserved.
|
# with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
|
||||||
# _AM_OUTPUT_DEPENDENCY_COMMANDS
|
# _AM_OUTPUT_DEPENDENCY_COMMANDS
|
||||||
# ------------------------------
|
# ------------------------------
|
||||||
AC_DEFUN([_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
|
# Older Autoconf quotes --file arguments for eval, but not when files
|
||||||
# are listed without --file. Let's play safe and only enable the eval
|
# are listed without --file. Let's play safe and only enable the eval
|
||||||
# if we detect the quoting.
|
# if we detect the quoting.
|
||||||
case $CONFIG_FILES in
|
# TODO: see whether this extra hack can be removed once we start
|
||||||
*\'*) eval set x "$CONFIG_FILES" ;;
|
# requiring Autoconf 2.70 or later.
|
||||||
*) set x $CONFIG_FILES ;;
|
AS_CASE([$CONFIG_FILES],
|
||||||
esac
|
[*\'*], [eval set x "$CONFIG_FILES"],
|
||||||
|
[*], [set x $CONFIG_FILES])
|
||||||
shift
|
shift
|
||||||
for mf
|
# Used to flag and report bootstrapping failures.
|
||||||
|
am_rc=0
|
||||||
|
for am_mf
|
||||||
do
|
do
|
||||||
# Strip MF so we end up with the name of the file.
|
# Strip MF so we end up with the name of the file.
|
||||||
mf=`echo "$mf" | sed -e 's/:.*$//'`
|
am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'`
|
||||||
# Check whether this is an Automake generated Makefile or not.
|
# Check whether this is an Automake generated Makefile which includes
|
||||||
# We used to match only the files named 'Makefile.in', but
|
# dependency-tracking related rules and includes.
|
||||||
# some people rename them; so instead we look at the file content.
|
# Grep'ing the whole file directly is not great: AIX grep has a line
|
||||||
# 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
|
|
||||||
# limit of 2048, but all sed's we know have understand at least 4000.
|
# 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
|
sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \
|
||||||
dirpart=`AS_DIRNAME("$mf")`
|
|| continue
|
||||||
else
|
am_dirpart=`AS_DIRNAME(["$am_mf"])`
|
||||||
continue
|
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
|
fi
|
||||||
# Extract the definition of DEPDIR, am__include, and am__quote
|
AS_UNSET([am_dirpart])
|
||||||
# from the Makefile without running 'make'.
|
AS_UNSET([am_filepart])
|
||||||
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
|
AS_UNSET([am_mf])
|
||||||
test -z "$DEPDIR" && continue
|
AS_UNSET([am_rc])
|
||||||
am__include=`sed -n 's/^am__include = //p' < "$mf"`
|
rm -f conftest-deps.mk
|
||||||
test -z "$am__include" && continue
|
|
||||||
am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
|
|
||||||
# Find all dependency output files, they are included files with
|
|
||||||
# $(DEPDIR) in their names. We invoke sed twice because it is the
|
|
||||||
# simplest approach to changing $(DEPDIR) to its actual value in the
|
|
||||||
# expansion.
|
|
||||||
for file in `sed -n "
|
|
||||||
s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
|
|
||||||
sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
|
|
||||||
# Make sure the directory exists.
|
|
||||||
test -f "$dirpart/$file" && continue
|
|
||||||
fdir=`AS_DIRNAME(["$file"])`
|
|
||||||
AS_MKDIR_P([$dirpart/$fdir])
|
|
||||||
# echo "creating $dirpart/$file"
|
|
||||||
echo '# dummy' > "$dirpart/$file"
|
|
||||||
done
|
|
||||||
done
|
|
||||||
}
|
}
|
||||||
])# _AM_OUTPUT_DEPENDENCY_COMMANDS
|
])# _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 macro should only be invoked once -- use via AC_REQUIRE.
|
||||||
#
|
#
|
||||||
# This code is only required when automatic dependency tracking
|
# This code is only required when automatic dependency tracking is enabled.
|
||||||
# is enabled. FIXME. This creates each '.P' file that we will
|
# This creates each '.Po' and '.Plo' makefile fragment that we'll need in
|
||||||
# need in order to bootstrap the dependency handling code.
|
# order to bootstrap the dependency handling code.
|
||||||
AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
|
AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
|
||||||
[AC_CONFIG_COMMANDS([depfiles],
|
[AC_CONFIG_COMMANDS([depfiles],
|
||||||
[test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
|
[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 -*-
|
# 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
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# 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
|
AC_REQUIRE([AC_PROG_MKDIR_P])dnl
|
||||||
# For better backward compatibility. To be removed once Automake 1.9.x
|
# For better backward compatibility. To be removed once Automake 1.9.x
|
||||||
# dies out for good. For more background, see:
|
# dies out for good. For more background, see:
|
||||||
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
|
# <https://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/msg00014.html>
|
||||||
AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
|
AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
|
||||||
# We need awk for the "check" target (and possibly the TAP driver). The
|
# We need awk for the "check" target (and possibly the TAP driver). The
|
||||||
# system "awk" is bad on some platforms.
|
# system "awk" is bad on some platforms.
|
||||||
|
@ -563,7 +553,7 @@ END
|
||||||
Aborting the configuration process, to ensure you take notice of the issue.
|
Aborting the configuration process, to ensure you take notice of the issue.
|
||||||
|
|
||||||
You can download and install GNU coreutils to get an 'rm' implementation
|
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
|
If you want to complete the configuration process using your problematic
|
||||||
'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
|
'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
|
||||||
|
@ -605,7 +595,7 @@ for _am_header in $config_headers :; do
|
||||||
done
|
done
|
||||||
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
|
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
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -626,7 +616,7 @@ if test x"${install_sh+set}" != xset; then
|
||||||
fi
|
fi
|
||||||
AC_SUBST([install_sh])])
|
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
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# 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 -*-
|
# 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
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -655,49 +645,42 @@ AC_SUBST([am__leading_dot])])
|
||||||
|
|
||||||
# AM_MAKE_INCLUDE()
|
# 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],
|
AC_DEFUN([AM_MAKE_INCLUDE],
|
||||||
[am_make=${MAKE-make}
|
[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive])
|
||||||
cat > confinc << 'END'
|
cat > confinc.mk << 'END'
|
||||||
am__doit:
|
am__doit:
|
||||||
@echo this is the am__doit target
|
@echo this is the am__doit target >confinc.out
|
||||||
.PHONY: am__doit
|
.PHONY: am__doit
|
||||||
END
|
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__include="#"
|
||||||
am__quote=
|
am__quote=
|
||||||
_am_result=none
|
# BSD make does it like this.
|
||||||
# First try GNU make style include.
|
echo '.include "confinc.mk" # ignored' > confmf.BSD
|
||||||
echo "include confinc" > confmf
|
# Other make implementations (GNU, Solaris 10, AIX) do it like this.
|
||||||
# Ignore all kinds of additional output from 'make'.
|
echo 'include confinc.mk # ignored' > confmf.GNU
|
||||||
case `$am_make -s -f confmf 2> /dev/null` in #(
|
_am_result=no
|
||||||
*the\ am__doit\ target*)
|
for s in GNU BSD; do
|
||||||
am__include=include
|
AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out])
|
||||||
am__quote=
|
AS_CASE([$?:`cat confinc.out 2>/dev/null`],
|
||||||
_am_result=GNU
|
['0:this is the am__doit target'],
|
||||||
;;
|
[AS_CASE([$s],
|
||||||
esac
|
[BSD], [am__include='.include' am__quote='"'],
|
||||||
# Now try BSD make style include.
|
[am__include='include' am__quote=''])])
|
||||||
if test "$am__include" = "#"; then
|
if test "$am__include" != "#"; then
|
||||||
echo '.include "confinc"' > confmf
|
_am_result="yes ($s style)"
|
||||||
case `$am_make -s -f confmf 2> /dev/null` in #(
|
break
|
||||||
*the\ am__doit\ target*)
|
|
||||||
am__include=.include
|
|
||||||
am__quote="\""
|
|
||||||
_am_result=BSD
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
fi
|
fi
|
||||||
AC_SUBST([am__include])
|
done
|
||||||
AC_SUBST([am__quote])
|
rm -f confinc.* confmf.*
|
||||||
AC_MSG_RESULT([$_am_result])
|
AC_MSG_RESULT([${_am_result}])
|
||||||
rm -f confinc confmf
|
AC_SUBST([am__include])])
|
||||||
])
|
AC_SUBST([am__quote])])
|
||||||
|
|
||||||
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
|
# 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
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -736,7 +719,7 @@ fi
|
||||||
|
|
||||||
# Helper functions for option handling. -*- Autoconf -*-
|
# 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
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -765,7 +748,7 @@ AC_DEFUN([_AM_SET_OPTIONS],
|
||||||
AC_DEFUN([_AM_IF_OPTION],
|
AC_DEFUN([_AM_IF_OPTION],
|
||||||
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
|
[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
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -812,7 +795,7 @@ AC_LANG_POP([C])])
|
||||||
# For backward compatibility.
|
# For backward compatibility.
|
||||||
AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
|
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
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# 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 -*-
|
# 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
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -912,7 +895,7 @@ AC_CONFIG_COMMANDS_PRE(
|
||||||
rm -f conftest.file
|
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
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -972,7 +955,7 @@ AC_SUBST([AM_BACKSLASH])dnl
|
||||||
_AM_SUBST_NOTMAKE([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
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -1000,7 +983,7 @@ fi
|
||||||
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
|
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
|
||||||
AC_SUBST([INSTALL_STRIP_PROGRAM])])
|
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
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# 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 -*-
|
# 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
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# 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_cflags_warn_all.m4])
|
||||||
m4_include([m4/ax_check_compile_flag.m4])
|
m4_include([m4/ax_check_compile_flag.m4])
|
||||||
m4_include([m4/ax_check_link_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/ax_require_defined.m4])
|
||||||
m4_include([m4/curses.m4])
|
m4_include([m4/curses.m4])
|
||||||
m4_include([m4/libgcrypt.m4])
|
m4_include([m4/libgcrypt.m4])
|
||||||
|
|
13
compile
13
compile
|
@ -1,9 +1,9 @@
|
||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Wrapper for compilers which do not understand '-c -o'.
|
# 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>.
|
# Written by Tom Tromey <tromey@cygnus.com>.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# 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
|
# As a special exception to the GNU General Public License, if you
|
||||||
# distribute this file as part of a program that contains a
|
# distribute this file as part of a program that contains a
|
||||||
|
@ -255,7 +255,8 @@ EOF
|
||||||
echo "compile $scriptversion"
|
echo "compile $scriptversion"
|
||||||
exit $?
|
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...
|
func_cl_wrapper "$@" # Doesn't return...
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
@ -339,9 +340,9 @@ exit $ret
|
||||||
# Local Variables:
|
# Local Variables:
|
||||||
# mode: shell-script
|
# mode: shell-script
|
||||||
# sh-indentation: 2
|
# 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-start: "scriptversion="
|
||||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
# time-stamp-time-zone: "UTC"
|
# time-stamp-time-zone: "UTC0"
|
||||||
# time-stamp-end: "; # UTC"
|
# time-stamp-end: "; # UTC"
|
||||||
# End:
|
# End:
|
||||||
|
|
572
config.guess
vendored
572
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) */
|
/* Darwin (MacOS/X) */
|
||||||
#undef HAVE_DARWIN
|
#undef HAVE_DARWIN
|
||||||
|
|
||||||
/* Define to 1 if you have the declaration of `OpenSSL_add_all_algorithms
|
/* Define to 1 if you have the declaration of `EVP_aes_256_cfb', and to 0 if
|
||||||
EVP_aes_256_cfb', and to 0 if you don't. */
|
you don't. */
|
||||||
#undef HAVE_DECL_OPENSSL_ADD_ALL_ALGORITHMS_EVP_AES_256_CFB
|
#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
|
/* Define to 1 if you have the declaration of `res_init', and to 0 if you
|
||||||
don't. */
|
don't. */
|
||||||
|
@ -83,9 +87,6 @@
|
||||||
/* FreeBSD */
|
/* FreeBSD */
|
||||||
#undef HAVE_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. */
|
/* Define to 1 if you have the <gcrypt.h> header file. */
|
||||||
#undef HAVE_GCRYPT_H
|
#undef HAVE_GCRYPT_H
|
||||||
|
|
||||||
|
@ -98,6 +99,9 @@
|
||||||
/* Define to 1 if you have the `gettimeofday' function. */
|
/* Define to 1 if you have the `gettimeofday' function. */
|
||||||
#undef HAVE_GETTIMEOFDAY
|
#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. */
|
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||||
#undef HAVE_INTTYPES_H
|
#undef HAVE_INTTYPES_H
|
||||||
|
|
||||||
|
@ -424,5 +428,8 @@
|
||||||
/* Defined if the __malloc__ attribute is not supported. */
|
/* Defined if the __malloc__ attribute is not supported. */
|
||||||
#undef __malloc__
|
#undef __malloc__
|
||||||
|
|
||||||
|
/* Defined if the __nonnull__ attribute is not supported. */
|
||||||
|
#undef __nonnull__
|
||||||
|
|
||||||
/* Defined if the __warn_unused_result__ attribute is not supported. */
|
/* Defined if the __warn_unused_result__ attribute is not supported. */
|
||||||
#undef __warn_unused_result__
|
#undef __warn_unused_result__
|
||||||
|
|
252
config.sub
vendored
252
config.sub
vendored
|
@ -1,8 +1,8 @@
|
||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Configuration validation subroutine script.
|
# 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
|
# 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
|
# 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.
|
# General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# 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
|
# As a special exception to the GNU General Public License, if you
|
||||||
# distribute this file as part of a program that contains a
|
# 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.
|
# Otherwise, we print the canonical config type on stdout and succeed.
|
||||||
|
|
||||||
# You can get the latest version of this script from:
|
# 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
|
# This file is supposed to be the same for all GNU packages
|
||||||
# and recognize all the CPU types, system types and aliases
|
# 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.
|
Canonicalize a configuration name.
|
||||||
|
|
||||||
Operation modes:
|
Options:
|
||||||
-h, --help print this help, then exit
|
-h, --help print this help, then exit
|
||||||
-t, --time-stamp print date of last modification, then exit
|
-t, --time-stamp print date of last modification, then exit
|
||||||
-v, --version print version number, then exit
|
-v, --version print version number, then exit
|
||||||
|
@ -67,7 +67,7 @@ Report bugs and patches to <config-patches@gnu.org>."
|
||||||
version="\
|
version="\
|
||||||
GNU config.sub ($timestamp)
|
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
|
This is free software; see the source for copying conditions. There is NO
|
||||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||||
|
@ -94,7 +94,7 @@ while test $# -gt 0 ; do
|
||||||
|
|
||||||
*local*)
|
*local*)
|
||||||
# First pass through any local machine types.
|
# First pass through any local machine types.
|
||||||
echo $1
|
echo "$1"
|
||||||
exit ;;
|
exit ;;
|
||||||
|
|
||||||
* )
|
* )
|
||||||
|
@ -112,7 +112,7 @@ esac
|
||||||
|
|
||||||
# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
|
# 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.
|
# 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
|
case $maybe_os in
|
||||||
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
|
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
|
||||||
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
|
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
|
||||||
|
@ -120,16 +120,16 @@ case $maybe_os in
|
||||||
kopensolaris*-gnu* | cloudabi*-eabi* | \
|
kopensolaris*-gnu* | cloudabi*-eabi* | \
|
||||||
storm-chaos* | os2-emx* | rtmk-nova*)
|
storm-chaos* | os2-emx* | rtmk-nova*)
|
||||||
os=-$maybe_os
|
os=-$maybe_os
|
||||||
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
|
basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
|
||||||
;;
|
;;
|
||||||
android-linux)
|
android-linux)
|
||||||
os=-linux-android
|
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/-[^-]*$//'`
|
basic_machine=`echo "$1" | sed 's/-[^-]*$//'`
|
||||||
if [ $basic_machine != $1 ]
|
if [ "$basic_machine" != "$1" ]
|
||||||
then os=`echo $1 | sed 's/.*-/-/'`
|
then os=`echo "$1" | sed 's/.*-/-/'`
|
||||||
else os=; fi
|
else os=; fi
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
@ -178,44 +178,44 @@ case $os in
|
||||||
;;
|
;;
|
||||||
-sco6)
|
-sco6)
|
||||||
os=-sco5v6
|
os=-sco5v6
|
||||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
|
||||||
;;
|
;;
|
||||||
-sco5)
|
-sco5)
|
||||||
os=-sco3.2v5
|
os=-sco3.2v5
|
||||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
|
||||||
;;
|
;;
|
||||||
-sco4)
|
-sco4)
|
||||||
os=-sco3.2v4
|
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]*)
|
-sco3.2.[4-9]*)
|
||||||
os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
|
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]*)
|
-sco3.2v[4-9]*)
|
||||||
# Don't forget version if it is 3.2v4 or newer.
|
# 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*)
|
-sco5v6*)
|
||||||
# Don't forget version if it is 3.2v4 or newer.
|
# 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*)
|
-sco*)
|
||||||
os=-sco3.2v2
|
os=-sco3.2v2
|
||||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
|
||||||
;;
|
;;
|
||||||
-udk*)
|
-udk*)
|
||||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
|
||||||
;;
|
;;
|
||||||
-isc)
|
-isc)
|
||||||
os=-isc2.2
|
os=-isc2.2
|
||||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
|
||||||
;;
|
;;
|
||||||
-clix*)
|
-clix*)
|
||||||
basic_machine=clipper-intergraph
|
basic_machine=clipper-intergraph
|
||||||
;;
|
;;
|
||||||
-isc*)
|
-isc*)
|
||||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
|
||||||
;;
|
;;
|
||||||
-lynx*178)
|
-lynx*178)
|
||||||
os=-lynxos178
|
os=-lynxos178
|
||||||
|
@ -227,10 +227,7 @@ case $os in
|
||||||
os=-lynxos
|
os=-lynxos
|
||||||
;;
|
;;
|
||||||
-ptx*)
|
-ptx*)
|
||||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
|
basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'`
|
||||||
;;
|
|
||||||
-windowsnt*)
|
|
||||||
os=`echo $os | sed -e 's/windowsnt/winnt/'`
|
|
||||||
;;
|
;;
|
||||||
-psos*)
|
-psos*)
|
||||||
os=-psos
|
os=-psos
|
||||||
|
@ -263,7 +260,7 @@ case $basic_machine in
|
||||||
| fido | fr30 | frv | ft32 \
|
| fido | fr30 | frv | ft32 \
|
||||||
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
||||||
| hexagon \
|
| hexagon \
|
||||||
| i370 | i860 | i960 | ia64 \
|
| i370 | i860 | i960 | ia16 | ia64 \
|
||||||
| ip2k | iq2000 \
|
| ip2k | iq2000 \
|
||||||
| k1om \
|
| k1om \
|
||||||
| le32 | le64 \
|
| le32 | le64 \
|
||||||
|
@ -299,7 +296,7 @@ case $basic_machine in
|
||||||
| nios | nios2 | nios2eb | nios2el \
|
| nios | nios2 | nios2eb | nios2el \
|
||||||
| ns16k | ns32k \
|
| ns16k | ns32k \
|
||||||
| open8 | or1k | or1knd | or32 \
|
| open8 | or1k | or1knd | or32 \
|
||||||
| pdp10 | pdp11 | pj | pjl \
|
| pdp10 | pj | pjl \
|
||||||
| powerpc | powerpc64 | powerpc64le | powerpcle \
|
| powerpc | powerpc64 | powerpc64le | powerpcle \
|
||||||
| pru \
|
| pru \
|
||||||
| pyramid \
|
| pyramid \
|
||||||
|
@ -315,7 +312,7 @@ case $basic_machine in
|
||||||
| ubicom32 \
|
| ubicom32 \
|
||||||
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
|
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
|
||||||
| visium \
|
| visium \
|
||||||
| we32k \
|
| wasm32 \
|
||||||
| x86 | xc16x | xstormy16 | xtensa \
|
| x86 | xc16x | xstormy16 | xtensa \
|
||||||
| z8k | z80)
|
| z8k | z80)
|
||||||
basic_machine=$basic_machine-unknown
|
basic_machine=$basic_machine-unknown
|
||||||
|
@ -336,7 +333,7 @@ case $basic_machine in
|
||||||
basic_machine=$basic_machine-unknown
|
basic_machine=$basic_machine-unknown
|
||||||
os=-none
|
os=-none
|
||||||
;;
|
;;
|
||||||
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
|
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65)
|
||||||
;;
|
;;
|
||||||
ms1)
|
ms1)
|
||||||
basic_machine=mt-unknown
|
basic_machine=mt-unknown
|
||||||
|
@ -365,7 +362,7 @@ case $basic_machine in
|
||||||
;;
|
;;
|
||||||
# Object if more than one company name word.
|
# 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
|
exit 1
|
||||||
;;
|
;;
|
||||||
# Recognize the basic CPU types with company name.
|
# Recognize the basic CPU types with company name.
|
||||||
|
@ -388,7 +385,7 @@ case $basic_machine in
|
||||||
| h8300-* | h8500-* \
|
| h8300-* | h8500-* \
|
||||||
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
|
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
|
||||||
| hexagon-* \
|
| hexagon-* \
|
||||||
| i*86-* | i860-* | i960-* | ia64-* \
|
| i*86-* | i860-* | i960-* | ia16-* | ia64-* \
|
||||||
| ip2k-* | iq2000-* \
|
| ip2k-* | iq2000-* \
|
||||||
| k1om-* \
|
| k1om-* \
|
||||||
| le32-* | le64-* \
|
| le32-* | le64-* \
|
||||||
|
@ -446,6 +443,7 @@ case $basic_machine in
|
||||||
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
|
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
|
||||||
| vax-* \
|
| vax-* \
|
||||||
| visium-* \
|
| visium-* \
|
||||||
|
| wasm32-* \
|
||||||
| we32k-* \
|
| we32k-* \
|
||||||
| x86-* | x86_64-* | xc16x-* | xps100-* \
|
| x86-* | x86_64-* | xc16x-* | xps100-* \
|
||||||
| xstormy16-* | xtensa*-* \
|
| xstormy16-* | xtensa*-* \
|
||||||
|
@ -459,7 +457,7 @@ case $basic_machine in
|
||||||
# Recognize the various machine names and aliases which stand
|
# Recognize the various machine names and aliases which stand
|
||||||
# for a CPU type and a company and sometimes even an OS.
|
# for a CPU type and a company and sometimes even an OS.
|
||||||
386bsd)
|
386bsd)
|
||||||
basic_machine=i386-unknown
|
basic_machine=i386-pc
|
||||||
os=-bsd
|
os=-bsd
|
||||||
;;
|
;;
|
||||||
3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
|
3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
|
||||||
|
@ -493,7 +491,7 @@ case $basic_machine in
|
||||||
basic_machine=x86_64-pc
|
basic_machine=x86_64-pc
|
||||||
;;
|
;;
|
||||||
amd64-*)
|
amd64-*)
|
||||||
basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
|
basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
|
||||||
;;
|
;;
|
||||||
amdahl)
|
amdahl)
|
||||||
basic_machine=580-amdahl
|
basic_machine=580-amdahl
|
||||||
|
@ -538,7 +536,7 @@ case $basic_machine in
|
||||||
os=-linux
|
os=-linux
|
||||||
;;
|
;;
|
||||||
blackfin-*)
|
blackfin-*)
|
||||||
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
|
basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'`
|
||||||
os=-linux
|
os=-linux
|
||||||
;;
|
;;
|
||||||
bluegene*)
|
bluegene*)
|
||||||
|
@ -546,13 +544,13 @@ case $basic_machine in
|
||||||
os=-cnk
|
os=-cnk
|
||||||
;;
|
;;
|
||||||
c54x-*)
|
c54x-*)
|
||||||
basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
|
basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
|
||||||
;;
|
;;
|
||||||
c55x-*)
|
c55x-*)
|
||||||
basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
|
basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
|
||||||
;;
|
;;
|
||||||
c6x-*)
|
c6x-*)
|
||||||
basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
|
basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
|
||||||
;;
|
;;
|
||||||
c90)
|
c90)
|
||||||
basic_machine=c90-cray
|
basic_machine=c90-cray
|
||||||
|
@ -641,7 +639,7 @@ case $basic_machine in
|
||||||
basic_machine=rs6000-bull
|
basic_machine=rs6000-bull
|
||||||
os=-bosx
|
os=-bosx
|
||||||
;;
|
;;
|
||||||
dpx2* | dpx2*-bull)
|
dpx2*)
|
||||||
basic_machine=m68k-bull
|
basic_machine=m68k-bull
|
||||||
os=-sysv3
|
os=-sysv3
|
||||||
;;
|
;;
|
||||||
|
@ -650,7 +648,7 @@ case $basic_machine in
|
||||||
os=$os"spe"
|
os=$os"spe"
|
||||||
;;
|
;;
|
||||||
e500v[12]-*)
|
e500v[12]-*)
|
||||||
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
|
basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
|
||||||
os=$os"spe"
|
os=$os"spe"
|
||||||
;;
|
;;
|
||||||
ebmon29k)
|
ebmon29k)
|
||||||
|
@ -742,9 +740,6 @@ case $basic_machine in
|
||||||
hp9k8[0-9][0-9] | hp8[0-9][0-9])
|
hp9k8[0-9][0-9] | hp8[0-9][0-9])
|
||||||
basic_machine=hppa1.0-hp
|
basic_machine=hppa1.0-hp
|
||||||
;;
|
;;
|
||||||
hppa-next)
|
|
||||||
os=-nextstep3
|
|
||||||
;;
|
|
||||||
hppaosf)
|
hppaosf)
|
||||||
basic_machine=hppa1.1-hp
|
basic_machine=hppa1.1-hp
|
||||||
os=-osf
|
os=-osf
|
||||||
|
@ -757,26 +752,26 @@ case $basic_machine in
|
||||||
basic_machine=i370-ibm
|
basic_machine=i370-ibm
|
||||||
;;
|
;;
|
||||||
i*86v32)
|
i*86v32)
|
||||||
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
|
||||||
os=-sysv32
|
os=-sysv32
|
||||||
;;
|
;;
|
||||||
i*86v4*)
|
i*86v4*)
|
||||||
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
|
||||||
os=-sysv4
|
os=-sysv4
|
||||||
;;
|
;;
|
||||||
i*86v)
|
i*86v)
|
||||||
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
|
||||||
os=-sysv
|
os=-sysv
|
||||||
;;
|
;;
|
||||||
i*86sol2)
|
i*86sol2)
|
||||||
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
|
||||||
os=-solaris2
|
os=-solaris2
|
||||||
;;
|
;;
|
||||||
i386mach)
|
i386mach)
|
||||||
basic_machine=i386-mach
|
basic_machine=i386-mach
|
||||||
os=-mach
|
os=-mach
|
||||||
;;
|
;;
|
||||||
i386-vsta | vsta)
|
vsta)
|
||||||
basic_machine=i386-unknown
|
basic_machine=i386-unknown
|
||||||
os=-vsta
|
os=-vsta
|
||||||
;;
|
;;
|
||||||
|
@ -795,19 +790,16 @@ case $basic_machine in
|
||||||
os=-sysv
|
os=-sysv
|
||||||
;;
|
;;
|
||||||
leon-*|leon[3-9]-*)
|
leon-*|leon[3-9]-*)
|
||||||
basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
|
basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'`
|
||||||
;;
|
;;
|
||||||
m68knommu)
|
m68knommu)
|
||||||
basic_machine=m68k-unknown
|
basic_machine=m68k-unknown
|
||||||
os=-linux
|
os=-linux
|
||||||
;;
|
;;
|
||||||
m68knommu-*)
|
m68knommu-*)
|
||||||
basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
|
basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'`
|
||||||
os=-linux
|
os=-linux
|
||||||
;;
|
;;
|
||||||
m88k-omron*)
|
|
||||||
basic_machine=m88k-omron
|
|
||||||
;;
|
|
||||||
magnum | m3230)
|
magnum | m3230)
|
||||||
basic_machine=mips-mips
|
basic_machine=mips-mips
|
||||||
os=-sysv
|
os=-sysv
|
||||||
|
@ -839,10 +831,10 @@ case $basic_machine in
|
||||||
os=-mint
|
os=-mint
|
||||||
;;
|
;;
|
||||||
mips3*-*)
|
mips3*-*)
|
||||||
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
|
basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`
|
||||||
;;
|
;;
|
||||||
mips3*)
|
mips3*)
|
||||||
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
|
basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown
|
||||||
;;
|
;;
|
||||||
monitor)
|
monitor)
|
||||||
basic_machine=m68k-rom68k
|
basic_machine=m68k-rom68k
|
||||||
|
@ -861,7 +853,7 @@ case $basic_machine in
|
||||||
os=-msdos
|
os=-msdos
|
||||||
;;
|
;;
|
||||||
ms1-*)
|
ms1-*)
|
||||||
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
|
basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'`
|
||||||
;;
|
;;
|
||||||
msys)
|
msys)
|
||||||
basic_machine=i686-pc
|
basic_machine=i686-pc
|
||||||
|
@ -948,6 +940,12 @@ case $basic_machine in
|
||||||
nsr-tandem)
|
nsr-tandem)
|
||||||
basic_machine=nsr-tandem
|
basic_machine=nsr-tandem
|
||||||
;;
|
;;
|
||||||
|
nsv-tandem)
|
||||||
|
basic_machine=nsv-tandem
|
||||||
|
;;
|
||||||
|
nsx-tandem)
|
||||||
|
basic_machine=nsx-tandem
|
||||||
|
;;
|
||||||
op50n-* | op60c-*)
|
op50n-* | op60c-*)
|
||||||
basic_machine=hppa1.1-oki
|
basic_machine=hppa1.1-oki
|
||||||
os=-proelf
|
os=-proelf
|
||||||
|
@ -980,7 +978,7 @@ case $basic_machine in
|
||||||
os=-linux
|
os=-linux
|
||||||
;;
|
;;
|
||||||
parisc-*)
|
parisc-*)
|
||||||
basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
|
basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'`
|
||||||
os=-linux
|
os=-linux
|
||||||
;;
|
;;
|
||||||
pbd)
|
pbd)
|
||||||
|
@ -996,7 +994,7 @@ case $basic_machine in
|
||||||
basic_machine=i386-pc
|
basic_machine=i386-pc
|
||||||
;;
|
;;
|
||||||
pc98-*)
|
pc98-*)
|
||||||
basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
|
basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'`
|
||||||
;;
|
;;
|
||||||
pentium | p5 | k5 | k6 | nexgen | viac3)
|
pentium | p5 | k5 | k6 | nexgen | viac3)
|
||||||
basic_machine=i586-pc
|
basic_machine=i586-pc
|
||||||
|
@ -1011,16 +1009,16 @@ case $basic_machine in
|
||||||
basic_machine=i786-pc
|
basic_machine=i786-pc
|
||||||
;;
|
;;
|
||||||
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
|
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-*)
|
pentiumpro-* | p6-* | 6x86-* | athlon-*)
|
||||||
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
|
basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
|
||||||
;;
|
;;
|
||||||
pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
|
pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
|
||||||
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
|
basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
|
||||||
;;
|
;;
|
||||||
pentium4-*)
|
pentium4-*)
|
||||||
basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
|
basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'`
|
||||||
;;
|
;;
|
||||||
pn)
|
pn)
|
||||||
basic_machine=pn-gould
|
basic_machine=pn-gould
|
||||||
|
@ -1030,23 +1028,23 @@ case $basic_machine in
|
||||||
ppc | ppcbe) basic_machine=powerpc-unknown
|
ppc | ppcbe) basic_machine=powerpc-unknown
|
||||||
;;
|
;;
|
||||||
ppc-* | ppcbe-*)
|
ppc-* | ppcbe-*)
|
||||||
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
|
basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
|
||||||
;;
|
;;
|
||||||
ppcle | powerpclittle)
|
ppcle | powerpclittle)
|
||||||
basic_machine=powerpcle-unknown
|
basic_machine=powerpcle-unknown
|
||||||
;;
|
;;
|
||||||
ppcle-* | powerpclittle-*)
|
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-unknown
|
||||||
;;
|
;;
|
||||||
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
|
ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
|
||||||
;;
|
;;
|
||||||
ppc64le | powerpc64little)
|
ppc64le | powerpc64little)
|
||||||
basic_machine=powerpc64le-unknown
|
basic_machine=powerpc64le-unknown
|
||||||
;;
|
;;
|
||||||
ppc64le-* | powerpc64little-*)
|
ppc64le-* | powerpc64little-*)
|
||||||
basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
|
basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'`
|
||||||
;;
|
;;
|
||||||
ps2)
|
ps2)
|
||||||
basic_machine=i386-ibm
|
basic_machine=i386-ibm
|
||||||
|
@ -1100,17 +1098,10 @@ case $basic_machine in
|
||||||
sequent)
|
sequent)
|
||||||
basic_machine=i386-sequent
|
basic_machine=i386-sequent
|
||||||
;;
|
;;
|
||||||
sh)
|
|
||||||
basic_machine=sh-hitachi
|
|
||||||
os=-hms
|
|
||||||
;;
|
|
||||||
sh5el)
|
sh5el)
|
||||||
basic_machine=sh5le-unknown
|
basic_machine=sh5le-unknown
|
||||||
;;
|
;;
|
||||||
sh64)
|
simso-wrs)
|
||||||
basic_machine=sh64-unknown
|
|
||||||
;;
|
|
||||||
sparclite-wrs | simso-wrs)
|
|
||||||
basic_machine=sparclite-wrs
|
basic_machine=sparclite-wrs
|
||||||
os=-vxworks
|
os=-vxworks
|
||||||
;;
|
;;
|
||||||
|
@ -1129,7 +1120,7 @@ case $basic_machine in
|
||||||
os=-sysv4
|
os=-sysv4
|
||||||
;;
|
;;
|
||||||
strongarm-* | thumb-*)
|
strongarm-* | thumb-*)
|
||||||
basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
|
basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'`
|
||||||
;;
|
;;
|
||||||
sun2)
|
sun2)
|
||||||
basic_machine=m68000-sun
|
basic_machine=m68000-sun
|
||||||
|
@ -1251,6 +1242,9 @@ case $basic_machine in
|
||||||
basic_machine=hppa1.1-winbond
|
basic_machine=hppa1.1-winbond
|
||||||
os=-proelf
|
os=-proelf
|
||||||
;;
|
;;
|
||||||
|
x64)
|
||||||
|
basic_machine=x86_64-pc
|
||||||
|
;;
|
||||||
xbox)
|
xbox)
|
||||||
basic_machine=i686-pc
|
basic_machine=i686-pc
|
||||||
os=-mingw32
|
os=-mingw32
|
||||||
|
@ -1259,20 +1253,12 @@ case $basic_machine in
|
||||||
basic_machine=xps100-honeywell
|
basic_machine=xps100-honeywell
|
||||||
;;
|
;;
|
||||||
xscale-* | xscalee[bl]-*)
|
xscale-* | xscalee[bl]-*)
|
||||||
basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
|
basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'`
|
||||||
;;
|
;;
|
||||||
ymp)
|
ymp)
|
||||||
basic_machine=ymp-cray
|
basic_machine=ymp-cray
|
||||||
os=-unicos
|
os=-unicos
|
||||||
;;
|
;;
|
||||||
z8k-*-coff)
|
|
||||||
basic_machine=z8k-unknown
|
|
||||||
os=-sim
|
|
||||||
;;
|
|
||||||
z80-*-coff)
|
|
||||||
basic_machine=z80-unknown
|
|
||||||
os=-sim
|
|
||||||
;;
|
|
||||||
none)
|
none)
|
||||||
basic_machine=none-none
|
basic_machine=none-none
|
||||||
os=-none
|
os=-none
|
||||||
|
@ -1301,10 +1287,6 @@ case $basic_machine in
|
||||||
vax)
|
vax)
|
||||||
basic_machine=vax-dec
|
basic_machine=vax-dec
|
||||||
;;
|
;;
|
||||||
pdp10)
|
|
||||||
# there are many clones, so DEC is not a safe bet
|
|
||||||
basic_machine=pdp10-unknown
|
|
||||||
;;
|
|
||||||
pdp11)
|
pdp11)
|
||||||
basic_machine=pdp11-dec
|
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)
|
sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
|
||||||
basic_machine=sh-unknown
|
basic_machine=sh-unknown
|
||||||
;;
|
;;
|
||||||
sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
|
|
||||||
basic_machine=sparc-sun
|
|
||||||
;;
|
|
||||||
cydra)
|
cydra)
|
||||||
basic_machine=cydra-cydrome
|
basic_machine=cydra-cydrome
|
||||||
;;
|
;;
|
||||||
|
@ -1336,7 +1315,7 @@ case $basic_machine in
|
||||||
# Make sure to match an already-canonicalized machine name.
|
# 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
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
@ -1344,10 +1323,10 @@ esac
|
||||||
# Here we canonicalize certain aliases for manufacturers.
|
# Here we canonicalize certain aliases for manufacturers.
|
||||||
case $basic_machine in
|
case $basic_machine in
|
||||||
*-digital*)
|
*-digital*)
|
||||||
basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
|
basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'`
|
||||||
;;
|
;;
|
||||||
*-commodore*)
|
*-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"" ]
|
if [ x"$os" != x"" ]
|
||||||
then
|
then
|
||||||
case $os in
|
case $os in
|
||||||
# First match some system type aliases
|
# First match some system type aliases that might get confused
|
||||||
# that might get confused with valid system types.
|
# with valid system types.
|
||||||
# -solaris* is a basic system type, with this one exception.
|
# -solaris* is a basic system type, with this one exception.
|
||||||
-auroraux)
|
-auroraux)
|
||||||
os=-auroraux
|
os=-auroraux
|
||||||
|
@ -1370,18 +1349,19 @@ case $os in
|
||||||
-solaris)
|
-solaris)
|
||||||
os=-solaris2
|
os=-solaris2
|
||||||
;;
|
;;
|
||||||
-svr4*)
|
|
||||||
os=-sysv4
|
|
||||||
;;
|
|
||||||
-unixware*)
|
-unixware*)
|
||||||
os=-sysv4.2uw
|
os=-sysv4.2uw
|
||||||
;;
|
;;
|
||||||
-gnu/linux*)
|
-gnu/linux*)
|
||||||
os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
|
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.
|
# 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.
|
# -sysv* is not here because it comes later, after sysvr4.
|
||||||
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
|
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
|
||||||
| -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
|
| -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
|
||||||
|
@ -1391,25 +1371,26 @@ case $os in
|
||||||
| -aos* | -aros* | -cloudabi* | -sortix* \
|
| -aos* | -aros* | -cloudabi* | -sortix* \
|
||||||
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
||||||
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
||||||
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
|
| -hiux* | -knetbsd* | -mirbsd* | -netbsd* \
|
||||||
| -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
|
| -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
|
||||||
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
|
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
|
||||||
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
||||||
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
||||||
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
|
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
|
||||||
| -chorusos* | -chorusrdb* | -cegcc* \
|
| -chorusos* | -chorusrdb* | -cegcc* | -glidix* \
|
||||||
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
||||||
| -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
|
| -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
|
||||||
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
|
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
|
||||||
| -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
|
| -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
|
||||||
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
|
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \
|
||||||
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
|
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
|
||||||
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
|
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
|
||||||
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
|
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
|
||||||
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
|
| -morphos* | -superux* | -rtmk* | -windiss* \
|
||||||
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
|
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
|
||||||
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
|
| -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.
|
# Remember, each alternative MUST END IN *, to match a version number.
|
||||||
;;
|
;;
|
||||||
-qnx*)
|
-qnx*)
|
||||||
|
@ -1426,12 +1407,12 @@ case $os in
|
||||||
-nto*)
|
-nto*)
|
||||||
os=`echo $os | sed -e 's|nto|nto-qnx|'`
|
os=`echo $os | sed -e 's|nto|nto-qnx|'`
|
||||||
;;
|
;;
|
||||||
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
|
-sim | -xray | -os68k* | -v88r* \
|
||||||
| -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
|
| -windows* | -osx | -abug | -netware* | -os9* \
|
||||||
| -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
|
| -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
|
||||||
;;
|
;;
|
||||||
-mac*)
|
-mac*)
|
||||||
os=`echo $os | sed -e 's|mac|macos|'`
|
os=`echo "$os" | sed -e 's|mac|macos|'`
|
||||||
;;
|
;;
|
||||||
-linux-dietlibc)
|
-linux-dietlibc)
|
||||||
os=-linux-dietlibc
|
os=-linux-dietlibc
|
||||||
|
@ -1440,10 +1421,10 @@ case $os in
|
||||||
os=`echo $os | sed -e 's|linux|linux-gnu|'`
|
os=`echo $os | sed -e 's|linux|linux-gnu|'`
|
||||||
;;
|
;;
|
||||||
-sunos5*)
|
-sunos5*)
|
||||||
os=`echo $os | sed -e 's|sunos5|solaris2|'`
|
os=`echo "$os" | sed -e 's|sunos5|solaris2|'`
|
||||||
;;
|
;;
|
||||||
-sunos6*)
|
-sunos6*)
|
||||||
os=`echo $os | sed -e 's|sunos6|solaris3|'`
|
os=`echo "$os" | sed -e 's|sunos6|solaris3|'`
|
||||||
;;
|
;;
|
||||||
-opened*)
|
-opened*)
|
||||||
os=-openedition
|
os=-openedition
|
||||||
|
@ -1454,12 +1435,6 @@ case $os in
|
||||||
-wince*)
|
-wince*)
|
||||||
os=-wince
|
os=-wince
|
||||||
;;
|
;;
|
||||||
-osfrose*)
|
|
||||||
os=-osfrose
|
|
||||||
;;
|
|
||||||
-osf*)
|
|
||||||
os=-osf
|
|
||||||
;;
|
|
||||||
-utek*)
|
-utek*)
|
||||||
os=-bsd
|
os=-bsd
|
||||||
;;
|
;;
|
||||||
|
@ -1506,7 +1481,7 @@ case $os in
|
||||||
-oss*)
|
-oss*)
|
||||||
os=-sysv3
|
os=-sysv3
|
||||||
;;
|
;;
|
||||||
-svr4)
|
-svr4*)
|
||||||
os=-sysv4
|
os=-sysv4
|
||||||
;;
|
;;
|
||||||
-svr3)
|
-svr3)
|
||||||
|
@ -1521,24 +1496,28 @@ case $os in
|
||||||
-ose*)
|
-ose*)
|
||||||
os=-ose
|
os=-ose
|
||||||
;;
|
;;
|
||||||
-es1800*)
|
|
||||||
os=-ose
|
|
||||||
;;
|
|
||||||
-xenix)
|
|
||||||
os=-xenix
|
|
||||||
;;
|
|
||||||
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
|
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
|
||||||
os=-mint
|
os=-mint
|
||||||
;;
|
;;
|
||||||
-aros*)
|
|
||||||
os=-aros
|
|
||||||
;;
|
|
||||||
-zvmoe)
|
-zvmoe)
|
||||||
os=-zvmoe
|
os=-zvmoe
|
||||||
;;
|
;;
|
||||||
-dicos*)
|
-dicos*)
|
||||||
os=-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*)
|
-nacl*)
|
||||||
;;
|
;;
|
||||||
-ios)
|
-ios)
|
||||||
|
@ -1548,7 +1527,7 @@ case $os in
|
||||||
*)
|
*)
|
||||||
# Get rid of the `-' at the beginning of $os.
|
# Get rid of the `-' at the beginning of $os.
|
||||||
os=`echo $os | sed 's/[^-]*-//'`
|
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
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
@ -1638,12 +1617,12 @@ case $basic_machine in
|
||||||
sparc-* | *-sun)
|
sparc-* | *-sun)
|
||||||
os=-sunos4.1.1
|
os=-sunos4.1.1
|
||||||
;;
|
;;
|
||||||
|
pru-*)
|
||||||
|
os=-elf
|
||||||
|
;;
|
||||||
*-be)
|
*-be)
|
||||||
os=-beos
|
os=-beos
|
||||||
;;
|
;;
|
||||||
*-haiku)
|
|
||||||
os=-haiku
|
|
||||||
;;
|
|
||||||
*-ibm)
|
*-ibm)
|
||||||
os=-aix
|
os=-aix
|
||||||
;;
|
;;
|
||||||
|
@ -1698,9 +1677,6 @@ case $basic_machine in
|
||||||
i370-*)
|
i370-*)
|
||||||
os=-mvs
|
os=-mvs
|
||||||
;;
|
;;
|
||||||
*-next)
|
|
||||||
os=-nextstep3
|
|
||||||
;;
|
|
||||||
*-gould)
|
*-gould)
|
||||||
os=-sysv
|
os=-sysv
|
||||||
;;
|
;;
|
||||||
|
@ -1810,15 +1786,15 @@ case $basic_machine in
|
||||||
vendor=stratus
|
vendor=stratus
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
|
basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"`
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
echo $basic_machine$os
|
echo "$basic_machine$os"
|
||||||
exit
|
exit
|
||||||
|
|
||||||
# Local variables:
|
# Local variables:
|
||||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
# eval: (add-hook 'write-file-functions 'time-stamp)
|
||||||
# time-stamp-start: "timestamp='"
|
# time-stamp-start: "timestamp='"
|
||||||
# time-stamp-format: "%:y-%02m-%02d"
|
# time-stamp-format: "%:y-%02m-%02d"
|
||||||
# time-stamp-end: "'"
|
# time-stamp-end: "'"
|
||||||
|
|
21
configure.ac
21
configure.ac
|
@ -1,9 +1,10 @@
|
||||||
dnl Process this file with autoconf to produce a configure script.
|
dnl Process this file with autoconf to produce a configure script.
|
||||||
|
|
||||||
|
origcflags="$CFLAGS"
|
||||||
|
|
||||||
AC_PREREQ(2.61)
|
AC_PREREQ(2.61)
|
||||||
AC_INIT([tinc], m4_esyscmd_s((git describe || echo UNKNOWN) | sed 's/release-//'))
|
AC_INIT([tinc], m4_esyscmd_s((git describe || echo UNKNOWN) | sed 's/release-//'))
|
||||||
AC_CONFIG_SRCDIR([src/tincd.c])
|
AC_CONFIG_SRCDIR([src/tincd.c])
|
||||||
AC_GNU_SOURCE
|
|
||||||
AM_INIT_AUTOMAKE([std-options subdir-objects nostdinc silent-rules -Wall])
|
AM_INIT_AUTOMAKE([std-options subdir-objects nostdinc silent-rules -Wall])
|
||||||
AC_CONFIG_HEADERS([config.h])
|
AC_CONFIG_HEADERS([config.h])
|
||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
|
@ -19,10 +20,12 @@ dnl Checks for programs.
|
||||||
AC_PROG_CC_C99
|
AC_PROG_CC_C99
|
||||||
AC_PROG_CPP
|
AC_PROG_CPP
|
||||||
AC_PROG_INSTALL
|
AC_PROG_INSTALL
|
||||||
AC_PROG_LN_S
|
|
||||||
|
|
||||||
AM_PROG_CC_C_O
|
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
|
dnl Check and set OS
|
||||||
|
|
||||||
AC_CANONICAL_HOST
|
AC_CANONICAL_HOST
|
||||||
|
@ -117,7 +120,7 @@ AC_ARG_WITH(systemd,
|
||||||
[ systemd=false ]
|
[ 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])])
|
[AS_IF([test "x$with_systemd" = "xno"], [systemd=false])])
|
||||||
|
|
||||||
AC_SUBST(systemd_path, $systemd_path)
|
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.
|
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||||
tinc_ATTRIBUTE(__malloc__)
|
tinc_ATTRIBUTE(__malloc__)
|
||||||
|
tinc_ATTRIBUTE(__nonnull__)
|
||||||
tinc_ATTRIBUTE(__warn_unused_result__)
|
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], , ,
|
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.
|
dnl Checks for library functions.
|
||||||
AC_TYPE_SIGNAL
|
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"]
|
[], [], [#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
|
AC_OUTPUT
|
||||||
|
|
8
depcomp
8
depcomp
|
@ -1,9 +1,9 @@
|
||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# depcomp - compile a program generating dependencies as side-effects
|
# 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
|
# 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
|
# 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.
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
# You should have received a copy of the GNU General Public License
|
# 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
|
# As a special exception to the GNU General Public License, if you
|
||||||
# distribute this file as part of a program that contains a
|
# distribute this file as part of a program that contains a
|
||||||
|
@ -783,7 +783,7 @@ exit 0
|
||||||
# Local Variables:
|
# Local Variables:
|
||||||
# mode: shell-script
|
# mode: shell-script
|
||||||
# sh-indentation: 2
|
# 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-start: "scriptversion="
|
||||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
# time-stamp-time-zone: "UTC0"
|
# time-stamp-time-zone: "UTC0"
|
||||||
|
|
|
@ -1,23 +1,13 @@
|
||||||
## Process this file with automake to get Makefile.in
|
## Process this file with automake to get Makefile.in
|
||||||
|
|
||||||
info_TEXINFOS = tinc.texi
|
info_TEXINFOS = tinc.texi
|
||||||
|
tinc_TEXINFOS = tincinclude.texi
|
||||||
|
|
||||||
man_MANS = tincd.8 tinc.8 tinc.conf.5 tinc-gui.8
|
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
|
CLEANFILES = *.html tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi
|
||||||
|
|
||||||
# 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 $<
|
|
||||||
|
|
||||||
tincd.8.html: tincd.8
|
tincd.8.html: tincd.8
|
||||||
$(AM_V_GEN)w3mman2html $? > $@
|
$(AM_V_GEN)w3mman2html $? > $@
|
||||||
|
@ -35,21 +25,20 @@ substitute = sed \
|
||||||
-e s,'@PACKAGE\@',"$(PACKAGE)",g \
|
-e s,'@PACKAGE\@',"$(PACKAGE)",g \
|
||||||
-e s,'@VERSION\@',"$(VERSION)",g \
|
-e s,'@VERSION\@',"$(VERSION)",g \
|
||||||
-e s,'@sysconfdir\@',"$(sysconfdir)",g \
|
-e s,'@sysconfdir\@',"$(sysconfdir)",g \
|
||||||
|
-e s,'@runstatedir\@',"$(runstatedir)",g \
|
||||||
-e s,'@localstatedir\@',"$(localstatedir)",g
|
-e s,'@localstatedir\@',"$(localstatedir)",g
|
||||||
|
|
||||||
tincd.8: tincd.8.in
|
tincd.8: $(srcdir)/tincd.8.in
|
||||||
$(AM_V_GEN)$(substitute) $? > $@
|
$(AM_V_GEN)$(substitute) $(srcdir)/tincd.8.in > $@
|
||||||
|
|
||||||
tinc.8: tinc.8.in
|
tinc.8: $(srcdir)/tinc.8.in
|
||||||
$(AM_V_GEN)$(substitute) $? > $@
|
$(AM_V_GEN)$(substitute) $(srcdir)/tinc.8.in > $@
|
||||||
|
|
||||||
tinc-gui.8: tinc-gui.8.in
|
tinc-gui.8: $(srcdir)/tinc-gui.8.in
|
||||||
$(AM_V_GEN)$(substitute) $? > $@
|
$(AM_V_GEN)$(substitute) $(srcdir)/tinc-gui.8.in > $@
|
||||||
|
|
||||||
tinc.conf.5: tinc.conf.5.in
|
tinc.conf.5: $(srcdir)/tinc.conf.5.in
|
||||||
$(AM_V_GEN)$(substitute) $? > $@
|
$(AM_V_GEN)$(substitute) $(srcdir)/tinc.conf.5.in > $@
|
||||||
|
|
||||||
tincinclude.texi: tincinclude.texi.in
|
tincinclude.texi: $(srcdir)/tincinclude.texi.in
|
||||||
$(AM_V_GEN)$(substitute) $? > $@
|
$(AM_V_GEN)$(substitute) $(srcdir)/tincinclude.texi.in > $@
|
||||||
|
|
||||||
tinc.texi: tincinclude.texi
|
|
||||||
|
|
|
@ -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@
|
# @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
|
# This Makefile.in is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# 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_PROGRAM = $(install_sh) -c
|
||||||
install_sh_SCRIPT = $(install_sh) -c
|
install_sh_SCRIPT = $(install_sh) -c
|
||||||
INSTALL_HEADER = $(INSTALL_DATA)
|
INSTALL_HEADER = $(INSTALL_DATA)
|
||||||
|
transform = $(program_transform_name)
|
||||||
NORMAL_INSTALL = :
|
NORMAL_INSTALL = :
|
||||||
PRE_INSTALL = :
|
PRE_INSTALL = :
|
||||||
POST_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_cflags_warn_all.m4 \
|
||||||
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
|
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
|
||||||
$(top_srcdir)/m4/ax_check_link_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/ax_require_defined.m4 \
|
||||||
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \
|
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \
|
||||||
$(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \
|
$(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \
|
||||||
|
@ -198,13 +200,8 @@ man8dir = $(mandir)/man8
|
||||||
NROFF = nroff
|
NROFF = nroff
|
||||||
MANS = $(man_MANS)
|
MANS = $(man_MANS)
|
||||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
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)
|
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@
|
ACLOCAL = @ACLOCAL@
|
||||||
AMTAR = @AMTAR@
|
AMTAR = @AMTAR@
|
||||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||||
|
@ -215,6 +212,12 @@ AWK = @AWK@
|
||||||
CC = @CC@
|
CC = @CC@
|
||||||
CCDEPMODE = @CCDEPMODE@
|
CCDEPMODE = @CCDEPMODE@
|
||||||
CFLAGS = @CFLAGS@
|
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@
|
CPP = @CPP@
|
||||||
CPPFLAGS = @CPPFLAGS@
|
CPPFLAGS = @CPPFLAGS@
|
||||||
CURSES_LIBS = @CURSES_LIBS@
|
CURSES_LIBS = @CURSES_LIBS@
|
||||||
|
@ -226,16 +229,18 @@ ECHO_N = @ECHO_N@
|
||||||
ECHO_T = @ECHO_T@
|
ECHO_T = @ECHO_T@
|
||||||
EGREP = @EGREP@
|
EGREP = @EGREP@
|
||||||
EXEEXT = @EXEEXT@
|
EXEEXT = @EXEEXT@
|
||||||
|
GCOV = @GCOV@
|
||||||
|
GENHTML = @GENHTML@
|
||||||
GREP = @GREP@
|
GREP = @GREP@
|
||||||
INSTALL = @INSTALL@
|
INSTALL = @INSTALL@
|
||||||
INSTALL_DATA = @INSTALL_DATA@
|
INSTALL_DATA = @INSTALL_DATA@
|
||||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||||
|
LCOV = @LCOV@
|
||||||
LDFLAGS = @LDFLAGS@
|
LDFLAGS = @LDFLAGS@
|
||||||
LIBOBJS = @LIBOBJS@
|
LIBOBJS = @LIBOBJS@
|
||||||
LIBS = @LIBS@
|
LIBS = @LIBS@
|
||||||
LN_S = @LN_S@
|
|
||||||
LTLIBOBJS = @LTLIBOBJS@
|
LTLIBOBJS = @LTLIBOBJS@
|
||||||
MAKEINFO = @MAKEINFO@
|
MAKEINFO = @MAKEINFO@
|
||||||
MINIUPNPC_LIBS = @MINIUPNPC_LIBS@
|
MINIUPNPC_LIBS = @MINIUPNPC_LIBS@
|
||||||
|
@ -250,6 +255,7 @@ PACKAGE_URL = @PACKAGE_URL@
|
||||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||||
READLINE_LIBS = @READLINE_LIBS@
|
READLINE_LIBS = @READLINE_LIBS@
|
||||||
|
SED = @SED@
|
||||||
SET_MAKE = @SET_MAKE@
|
SET_MAKE = @SET_MAKE@
|
||||||
SHELL = @SHELL@
|
SHELL = @SHELL@
|
||||||
STRIP = @STRIP@
|
STRIP = @STRIP@
|
||||||
|
@ -307,13 +313,15 @@ top_build_prefix = @top_build_prefix@
|
||||||
top_builddir = @top_builddir@
|
top_builddir = @top_builddir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
info_TEXINFOS = tinc.texi
|
info_TEXINFOS = tinc.texi
|
||||||
|
tinc_TEXINFOS = tincinclude.texi
|
||||||
man_MANS = tincd.8 tinc.8 tinc.conf.5 tinc-gui.8
|
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
|
CLEANFILES = *.html tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi
|
||||||
substitute = sed \
|
substitute = sed \
|
||||||
-e s,'@PACKAGE\@',"$(PACKAGE)",g \
|
-e s,'@PACKAGE\@',"$(PACKAGE)",g \
|
||||||
-e s,'@VERSION\@',"$(VERSION)",g \
|
-e s,'@VERSION\@',"$(VERSION)",g \
|
||||||
-e s,'@sysconfdir\@',"$(sysconfdir)",g \
|
-e s,'@sysconfdir\@',"$(sysconfdir)",g \
|
||||||
|
-e s,'@runstatedir\@',"$(runstatedir)",g \
|
||||||
-e s,'@localstatedir\@',"$(localstatedir)",g
|
-e s,'@localstatedir\@',"$(localstatedir)",g
|
||||||
|
|
||||||
all: all-am
|
all: all-am
|
||||||
|
@ -337,8 +345,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||||
*config.status*) \
|
*config.status*) \
|
||||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||||
*) \
|
*) \
|
||||||
echo ' 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__depfiles_maybe);; \
|
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
|
||||||
esac;
|
esac;
|
||||||
|
|
||||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||||
|
@ -393,10 +401,10 @@ $(am__aclocal_m4_deps):
|
||||||
else \
|
else \
|
||||||
rm -rf $(@:.html=.htp); exit 1; \
|
rm -rf $(@:.html=.htp); exit 1; \
|
||||||
fi
|
fi
|
||||||
$(srcdir)/tinc.info: tinc.texi
|
$(srcdir)/tinc.info: tinc.texi $(tinc_TEXINFOS)
|
||||||
tinc.dvi: tinc.texi
|
tinc.dvi: tinc.texi $(tinc_TEXINFOS)
|
||||||
tinc.pdf: tinc.texi
|
tinc.pdf: tinc.texi $(tinc_TEXINFOS)
|
||||||
tinc.html: tinc.texi
|
tinc.html: tinc.texi $(tinc_TEXINFOS)
|
||||||
.dvi.ps:
|
.dvi.ps:
|
||||||
$(AM_V_DVIPS)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
|
$(AM_V_DVIPS)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
|
||||||
$(DVIPS) $(AM_V_texinfo) -o $@ $<
|
$(DVIPS) $(AM_V_texinfo) -o $@ $<
|
||||||
|
@ -583,7 +591,10 @@ ctags CTAGS:
|
||||||
cscope cscopelist:
|
cscope cscopelist:
|
||||||
|
|
||||||
|
|
||||||
distdir: $(DISTFILES)
|
distdir: $(BUILT_SOURCES)
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
||||||
|
|
||||||
|
distdir-am: $(DISTFILES)
|
||||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||||
list='$(DISTFILES)'; \
|
list='$(DISTFILES)'; \
|
||||||
|
@ -835,12 +846,6 @@ uninstall-man: uninstall-man5 uninstall-man8
|
||||||
.PRECIOUS: Makefile
|
.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
|
tincd.8.html: tincd.8
|
||||||
$(AM_V_GEN)w3mman2html $? > $@
|
$(AM_V_GEN)w3mman2html $? > $@
|
||||||
|
|
||||||
|
@ -853,22 +858,20 @@ tinc-gui.8.html: tinc-gui.8
|
||||||
tinc.conf.5.html: tinc.conf.5
|
tinc.conf.5.html: tinc.conf.5
|
||||||
$(AM_V_GEN)w3mman2html $? > $@
|
$(AM_V_GEN)w3mman2html $? > $@
|
||||||
|
|
||||||
tincd.8: tincd.8.in
|
tincd.8: $(srcdir)/tincd.8.in
|
||||||
$(AM_V_GEN)$(substitute) $? > $@
|
$(AM_V_GEN)$(substitute) $(srcdir)/tincd.8.in > $@
|
||||||
|
|
||||||
tinc.8: tinc.8.in
|
tinc.8: $(srcdir)/tinc.8.in
|
||||||
$(AM_V_GEN)$(substitute) $? > $@
|
$(AM_V_GEN)$(substitute) $(srcdir)/tinc.8.in > $@
|
||||||
|
|
||||||
tinc-gui.8: tinc-gui.8.in
|
tinc-gui.8: $(srcdir)/tinc-gui.8.in
|
||||||
$(AM_V_GEN)$(substitute) $? > $@
|
$(AM_V_GEN)$(substitute) $(srcdir)/tinc-gui.8.in > $@
|
||||||
|
|
||||||
tinc.conf.5: tinc.conf.5.in
|
tinc.conf.5: $(srcdir)/tinc.conf.5.in
|
||||||
$(AM_V_GEN)$(substitute) $? > $@
|
$(AM_V_GEN)$(substitute) $(srcdir)/tinc.conf.5.in > $@
|
||||||
|
|
||||||
tincinclude.texi: tincinclude.texi.in
|
tincinclude.texi: $(srcdir)/tincinclude.texi.in
|
||||||
$(AM_V_GEN)$(substitute) $? > $@
|
$(AM_V_GEN)$(substitute) $(srcdir)/tincinclude.texi.in > $@
|
||||||
|
|
||||||
tinc.texi: tincinclude.texi
|
|
||||||
|
|
||||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
# 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.
|
# 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
|
5100
doc/texinfo.tex
5100
doc/texinfo.tex
File diff suppressed because it is too large
Load diff
|
@ -30,7 +30,7 @@ Use the cookie from
|
||||||
.Ar FILENAME
|
.Ar FILENAME
|
||||||
to authenticate with a running tinc daemon.
|
to authenticate with a running tinc daemon.
|
||||||
If unspecified, the default is
|
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
|
.It Fl -help
|
||||||
Display short list of options.
|
Display short list of options.
|
||||||
.El
|
.El
|
||||||
|
|
|
@ -7,10 +7,11 @@
|
||||||
.Nd tinc VPN control
|
.Nd tinc VPN control
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
.Op Fl cn
|
.Op Fl bcn
|
||||||
.Op Fl -config Ns = Ns Ar DIR
|
.Op Fl -config Ns = Ns Ar DIR
|
||||||
.Op Fl -net Ns = Ns Ar NETNAME
|
.Op Fl -net Ns = Ns Ar NETNAME
|
||||||
.Op Fl -pidfile Ns = Ns Ar FILENAME
|
.Op Fl -pidfile Ns = Ns Ar FILENAME
|
||||||
|
.Op Fl -batch
|
||||||
.Op Fl -force
|
.Op Fl -force
|
||||||
.Op Fl -help
|
.Op Fl -help
|
||||||
.Op Fl -version
|
.Op Fl -version
|
||||||
|
@ -54,7 +55,9 @@ Use the cookie from
|
||||||
.Ar FILENAME
|
.Ar FILENAME
|
||||||
to authenticate with a running tinc daemon.
|
to authenticate with a running tinc daemon.
|
||||||
If unspecified, the default is
|
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
|
.It Fl -force
|
||||||
Force some commands to work despite warnings.
|
Force some commands to work despite warnings.
|
||||||
.It Fl -help
|
.It Fl -help
|
||||||
|
@ -249,7 +252,7 @@ to allow a signature from any node whose public key is known.
|
||||||
If no
|
If no
|
||||||
.Ar filename
|
.Ar filename
|
||||||
is given, the file is read from standard input.
|
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,
|
a copy of the input with the signature removed is written to standard output,
|
||||||
and the exit code will be zero.
|
and the exit code will be zero.
|
||||||
If the verification failed,
|
If the verification failed,
|
||||||
|
|
|
@ -114,7 +114,7 @@ If
|
||||||
.Qq any
|
.Qq any
|
||||||
is selected, then depending on the operating system both IPv4 and IPv6 or just
|
is selected, then depending on the operating system both IPv4 and IPv6 or just
|
||||||
IPv6 listening sockets will be created.
|
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,
|
If set to yes,
|
||||||
.Nm tinc
|
.Nm tinc
|
||||||
will automatically set up meta connections to other nodes,
|
will automatically set up meta connections to other nodes,
|
||||||
|
@ -177,7 +177,7 @@ line).
|
||||||
.Pp
|
.Pp
|
||||||
If you don't specify a host with
|
If you don't specify a host with
|
||||||
.Va ConnectTo
|
.Va ConnectTo
|
||||||
and don't enable
|
and have disabled
|
||||||
.Va AutoConnect ,
|
.Va AutoConnect ,
|
||||||
.Nm tinc
|
.Nm tinc
|
||||||
won't try to connect to other daemons at all,
|
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
|
Create a UNIX socket with the filename specified by
|
||||||
.Va Device ,
|
.Va Device ,
|
||||||
or
|
or
|
||||||
.Pa @localstatedir@/run/ Ns Ar NETNAME Ns Pa .umlsocket
|
.Pa @runstatedir@/ Ns Ar NETNAME Ns Pa .umlsocket
|
||||||
if not specified.
|
if not specified.
|
||||||
.Nm tinc
|
.Nm tinc
|
||||||
will wait for a User Mode Linux instance to connect to this socket.
|
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
|
using the UNIX socket specified by
|
||||||
.Va Device ,
|
.Va Device ,
|
||||||
or
|
or
|
||||||
.Pa @localstatedir@/run/vde.ctl
|
.Pa @runstatedir@/vde.ctl
|
||||||
if not specified.
|
if not specified.
|
||||||
.El
|
.El
|
||||||
Also, in case tinc does not seem to correctly interpret packets received from the virtual network device,
|
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
|
.Pp
|
||||||
This is the default mode, and unless you really know you need another forwarding mode, don't change it.
|
This is the default mode, and unless you really know you need another forwarding mode, don't change it.
|
||||||
.It kernel
|
.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,
|
This is less efficient, but allows the kernel to apply its routing and firewall rules on them,
|
||||||
and can also help debugging.
|
and can also help debugging.
|
||||||
|
Incoming packets using the SPTPS protocol are dropped, since they are end-to-end encrypted.
|
||||||
.El
|
.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
|
.It Va Hostnames Li = yes | no Pq no
|
||||||
This option selects whether IP addresses (both real and on the VPN) should
|
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
|
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/
|
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /invitations/
|
||||||
This directory contains outstanding invitations.
|
This directory contains outstanding invitations.
|
||||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /invitation-data
|
.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
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr tincd 8 ,
|
.Xr tincd 8 ,
|
||||||
|
|
514
doc/tinc.info
514
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
|
INFO-DIR-SECTION Networking tools
|
||||||
START-INFO-DIR-ENTRY
|
START-INFO-DIR-ENTRY
|
||||||
* tinc: (tinc). The tinc Manual.
|
* tinc: (tinc). The tinc Manual.
|
||||||
END-INFO-DIR-ENTRY
|
END-INFO-DIR-ENTRY
|
||||||
|
|
||||||
This is the info manual for tinc version 1.1pre14-62-g958a751e, a
|
This is the info manual for tinc version 1.1pre17, a Virtual Private
|
||||||
Virtual Private Network daemon.
|
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>.
|
<guus@tinc-vpn.org> and Wessel Dankers <wsl@tinc-vpn.org>.
|
||||||
|
|
||||||
Permission is granted to make and distribute verbatim copies of this
|
Permission is granted to make and distribute verbatim copies of this
|
||||||
|
@ -285,7 +285,7 @@ File: tinc.info, Node: Libraries, Prev: Configuring the kernel, Up: Preparati
|
||||||
=============
|
=============
|
||||||
|
|
||||||
Before you can configure or build tinc, you need to have the LibreSSL or
|
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,
|
system. If you try to configure tinc without having them installed,
|
||||||
configure will give you an error message, and stop.
|
configure will give you an error message, and stop.
|
||||||
|
|
||||||
|
@ -293,7 +293,7 @@ configure will give you an error message, and stop.
|
||||||
|
|
||||||
* LibreSSL/OpenSSL::
|
* LibreSSL/OpenSSL::
|
||||||
* zlib::
|
* zlib::
|
||||||
* lzo::
|
* LZO::
|
||||||
* libcurses::
|
* libcurses::
|
||||||
* libreadline::
|
* 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
|
For all cryptography-related functions, tinc uses the functions provided
|
||||||
by the LibreSSL or the OpenSSL library.
|
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
|
tinc for build. Support for running tinc with other cryptographic
|
||||||
libraries installed _may_ be added in the future.
|
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
|
If your operating system comes neither with LibreSSL or OpenSSL, you
|
||||||
have to install one manually. It is recommended that you get the latest
|
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
|
how to configure, build and install this package are included within the
|
||||||
package. Please make sure you build development and runtime libraries
|
package. Please make sure you build development and runtime libraries
|
||||||
(which is the default).
|
(which is the default).
|
||||||
|
@ -357,7 +357,7 @@ present the following exemption:
|
||||||
Markus F.X.J. Oberhumer
|
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
|
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
|
For the optional compression of UDP packets, tinc uses the functions
|
||||||
provided by the zlib library.
|
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
|
configure script. You can either install the zlib library, or disable
|
||||||
support for zlib compression by using the "-disable-zlib" option when
|
support for zlib compression by using the "-disable-zlib" option when
|
||||||
running the configure script. Note that if you disable support for
|
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.
|
of this package.
|
||||||
|
|
||||||
If you have to install zlib manually, you can get the source code from
|
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
|
install this package are included within the package. Please make sure
|
||||||
you build development and runtime libraries (which is the default).
|
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.
|
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
|
configure script. You can either install the LZO library, or disable
|
||||||
support for LZO compression by using the "-disable-lzo" option when
|
support for LZO compression by using the "-disable-lzo" option when
|
||||||
running the configure script. Note that if you disable support for LZO,
|
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
|
available. Make sure you install the development AND runtime versions
|
||||||
of this package.
|
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
|
<https://www.oberhumer.com/opensource/lzo/>. Instructions on how to
|
||||||
configure, build and install this package are included within the
|
configure, build and install this package are included within the
|
||||||
package. Please make sure you build development and runtime libraries
|
package. Please make sure you build development and runtime libraries
|
||||||
(which is the default).
|
(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
|
2.2.4 libcurses
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
For the "tinc top" command, tinc requires a curses library.
|
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
|
configure script. You can either install a suitable curses library, or
|
||||||
disable all functionality that depends on a curses library by using the
|
disable all functionality that depends on a curses library by using the
|
||||||
"-disable-curses" option when running the configure script.
|
"-disable-curses" option when running the configure script.
|
||||||
|
|
||||||
There are several curses libraries. It is recommended that you install
|
There are several curses libraries. It is recommended that you install
|
||||||
"ncurses" (<http://invisible-island.net/ncurses/>), however other curses
|
"ncurses" (<https://invisible-island.net/ncurses/>), however other
|
||||||
libraries should also work. In particular, "PDCurses"
|
curses libraries should also work. In particular, "PDCurses"
|
||||||
(<http://pdcurses.sourceforge.net/>) is recommended if you want to
|
(<https://pdcurses.sourceforge.io/>) is recommended if you want to
|
||||||
compile tinc for Windows.
|
compile tinc for Windows.
|
||||||
|
|
||||||
You can use your operating system's package manager to install this if
|
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
|
For the "tinc" command's shell functionality, tinc uses the readline
|
||||||
library.
|
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,
|
configure script. You can either install a suitable readline library,
|
||||||
or disable all functionality that depends on a readline library by using
|
or disable all functionality that depends on a readline library by using
|
||||||
the "-disable-readline" option when running the configure script.
|
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.
|
of this package.
|
||||||
|
|
||||||
If you have to install libreadline manually, you can get the source code
|
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
|
configure, build and install this package are included within the
|
||||||
package. Please make sure you build development and runtime libraries
|
package. Please make sure you build development and runtime libraries
|
||||||
(which is the default).
|
(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
|
can only be answered by yourself, you will not find the answers in this
|
||||||
documentation. Make sure you have an adequate understanding of networks
|
documentation. Make sure you have an adequate understanding of networks
|
||||||
in general. A good resource on networking is the Linux Network
|
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
|
If you have everything clearly pictured in your mind, proceed in the
|
||||||
following order: First, create the initial configuration files and
|
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
|
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.
|
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.
|
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
|
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
|
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'
|
in the configuration file tinc.conf. It will then start listening for
|
||||||
values pointing to other tinc daemons in that file, it will try to
|
incoming connection from other daemons, and will by default also
|
||||||
connect to those other daemons. Whether this succeeds or not and
|
automatically try to connect to known peers. By default, tinc will try
|
||||||
whether 'ConnectTo' is specified or not, tinc will listen for incoming
|
to keep at least 3 working meta-connections alive at all times.
|
||||||
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.
|
|
||||||
|
|
||||||
There is no real distinction between a server and a client in tinc. If
|
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
|
you wish, you can view a tinc daemon without a 'ConnectTo' statement in
|
||||||
server, and one which does specify such a value as a client. It does
|
tinc.conf and 'AutoConnect = no' as a server, and one which does have
|
||||||
not matter if two tinc daemons have a 'ConnectTo' value pointing to each
|
one or more 'ConnectTo' statements or 'Autoconnect = yes' (which is the
|
||||||
other however.
|
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.
|
Connections specified using 'ConnectTo' are so-called meta-connections.
|
||||||
Tinc daemons exchange information about all other daemon they know about
|
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.
|
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
|
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.
|
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
|
'/etc/tinc/NETNAME/tinc.conf' and at least one other file in the
|
||||||
directory '/etc/tinc/NETNAME/hosts/'.
|
directory '/etc/tinc/NETNAME/hosts/'.
|
||||||
|
|
||||||
An optionnal directory '/etc/tinc/NETNAME/conf.d' can be added from
|
An optional directory '/etc/tinc/NETNAME/conf.d' can be added from which
|
||||||
which any .conf file will be read.
|
any .conf file will be read.
|
||||||
|
|
||||||
These file consists of comments (lines started with a #) or assignments
|
These file consists of comments (lines started with a #) or assignments
|
||||||
in the form of
|
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
|
system both IPv4 and IPv6 or just IPv6 listening sockets will be
|
||||||
created.
|
created.
|
||||||
|
|
||||||
AutoConnect = <yes|no> (no) [experimental]
|
AutoConnect = <yes|no> (yes)
|
||||||
If set to yes, tinc will automatically set up meta connections to
|
If set to yes, tinc will automatically set up meta connections to
|
||||||
other nodes, without requiring CONNECTTO variables.
|
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
|
names should be known to this tinc daemon (i.e., there should be a
|
||||||
host configuration file for the name on the ConnectTo line).
|
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
|
AutoConnect, tinc won't try to connect to other daemons at all, and
|
||||||
will instead just listen for incoming connections.
|
will instead just listen for incoming connections.
|
||||||
|
|
||||||
|
@ -966,10 +961,18 @@ Forwarding = <off|internal|kernel> (internal) [experimental]
|
||||||
another forwarding mode, don't change it.
|
another forwarding mode, don't change it.
|
||||||
|
|
||||||
kernel
|
kernel
|
||||||
Incoming packets are always sent to the TUN/TAP device, even
|
Incoming packets using the legacy protocol are always sent to
|
||||||
if the packets are not for the local node. This is less
|
the TUN/TAP device, even if the packets are not for the local
|
||||||
efficient, but allows the kernel to apply its routing and
|
node. This is less efficient, but allows the kernel to apply
|
||||||
firewall rules on them, and can also help debugging.
|
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)
|
Hostnames = <yes|no> (no)
|
||||||
This option selects whether IP addresses (both real and on the VPN)
|
This option selects whether IP addresses (both real and on the VPN)
|
||||||
|
@ -1093,7 +1096,7 @@ PriorityInheritance = <yes|no> (no) [experimental]
|
||||||
PrivateKey = <KEY> [obsolete]
|
PrivateKey = <KEY> [obsolete]
|
||||||
This is the RSA private key for tinc. However, for safety reasons
|
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.
|
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.
|
configuration file.
|
||||||
|
|
||||||
PrivateKeyFile = <PATH> ('/etc/tinc/NETNAME/rsa_key.priv')
|
PrivateKeyFile = <PATH> ('/etc/tinc/NETNAME/rsa_key.priv')
|
||||||
|
@ -1243,7 +1246,7 @@ ClampMSS = <yes|no> (yes)
|
||||||
Compression = <LEVEL> (0)
|
Compression = <LEVEL> (0)
|
||||||
This option sets the level of compression used for UDP packets.
|
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
|
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)
|
Digest = <DIGEST> (sha1)
|
||||||
The digest algorithm used to authenticate UDP packets using the
|
The digest algorithm used to authenticate UDP packets using the
|
||||||
|
@ -1299,9 +1302,9 @@ PublicKeyFile = <PATH> [obsolete]
|
||||||
Subnet = <ADDRESS[/PREFIXLENGTH[#WEIGHT]]>
|
Subnet = <ADDRESS[/PREFIXLENGTH[#WEIGHT]]>
|
||||||
The subnet which this tinc daemon will serve. Tinc tries to look
|
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
|
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
|
appropriate subnet. If the packet matches a subnet, it will be
|
||||||
to the daemon who has this subnet in his host configuration file.
|
sent to the daemon who has this subnet in his host configuration
|
||||||
Multiple subnet lines can be specified for each daemon.
|
file. Multiple subnet lines can be specified for each daemon.
|
||||||
|
|
||||||
Subnets can either be single MAC, IPv4 or IPv6 addresses, in which
|
Subnets can either be single MAC, IPv4 or IPv6 addresses, in which
|
||||||
case a subnet consisting of only that single address is assumed, or
|
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
|
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.
|
Step 2. Exchanging configuration files.
|
||||||
.......................................
|
.......................................
|
||||||
|
|
||||||
If your daemon has a ConnectTo = bar statement in its 'tinc.conf' file,
|
In order for two tinc daemons to be able to connect to each other, they
|
||||||
or if bar has a ConnectTo your daemon, then you both need each other's
|
each need the other's host configuration files. So if you want foo to
|
||||||
host configuration files. You should send 'hosts/NAME' to bar, and bar
|
be able to connect with bar, You should send 'hosts/NAME' to bar, and
|
||||||
should send you his file which you should move to 'hosts/bar'. If you
|
bar should send you his file which you should move to 'hosts/bar'. If
|
||||||
are on a UNIX platform, you can easily send an email containing the
|
you are on a UNIX platform, you can easily send an email containing the
|
||||||
necessary information using the following command (assuming the owner of
|
necessary information using the following command (assuming the owner of
|
||||||
bar has the email address bar@example.org):
|
bar has the email address bar@example.org):
|
||||||
|
|
||||||
|
@ -1552,10 +1543,9 @@ following command:
|
||||||
| ssh bar.example.org tinc -n NETNAME exchange \
|
| ssh bar.example.org tinc -n NETNAME exchange \
|
||||||
| tinc -n NETNAME import
|
| tinc -n NETNAME import
|
||||||
|
|
||||||
You should repeat this for all nodes you ConnectTo, or which ConnectTo
|
You can repeat this for a few other nodes as well. It is not necessary
|
||||||
you. However, remember that you do not need to ConnectTo all nodes in
|
to manually exchange host config files between all nodes; after the
|
||||||
the VPN; it is only necessary to create one or a few meta-connections,
|
initial connections are made tinc will learn about all the other nodes
|
||||||
after the connections are made tinc will learn about all the other nodes
|
|
||||||
in the VPN, and will automatically make other connections as necessary.
|
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':
|
and in '/etc/tinc/company/tinc.conf':
|
||||||
|
|
||||||
Name = BranchB
|
Name = BranchB
|
||||||
ConnectTo = BranchA
|
|
||||||
|
|
||||||
Note here that the internal address (on eth0) doesn't have to be the
|
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
|
same as on the VPN interface.
|
||||||
node will always try to connect to BranchA.
|
|
||||||
|
|
||||||
On all hosts, in '/etc/tinc/company/hosts/BranchB':
|
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':
|
and in '/etc/tinc/company/tinc.conf':
|
||||||
|
|
||||||
Name = BranchC
|
Name = BranchC
|
||||||
ConnectTo = BranchA
|
|
||||||
|
|
||||||
C already has another daemon that runs on port 655, so they have to
|
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
|
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':
|
and in '/etc/tinc/company/tinc.conf':
|
||||||
|
|
||||||
Name = BranchD
|
Name = BranchD
|
||||||
ConnectTo = BranchC
|
|
||||||
|
|
||||||
D will be connecting to C, which has a tincd running for this network on
|
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.
|
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
|
facility. If FILE is omitted, the default is
|
||||||
'/var/log/tinc.NETNAME.log'.
|
'/var/log/tinc.NETNAME.log'.
|
||||||
|
|
||||||
|
'--pidfile=FILE'
|
||||||
|
Write PID to FILE instead of '/var/run/tinc.NETNAME.pid'.
|
||||||
|
|
||||||
'--bypass-security'
|
'--bypass-security'
|
||||||
Disables encryption and authentication. Only useful for debugging.
|
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
|
chroot is performed after all the initialization is done, after
|
||||||
writing pid files and opening network sockets.
|
writing pid files and opening network sockets.
|
||||||
|
|
||||||
Note that this option alone does not do any good without -U/-user,
|
This option is best used in combination with the -U/-user option
|
||||||
below.
|
described below.
|
||||||
|
|
||||||
Note also that tinc can't run scripts anymore (such as tinc-down or
|
You will need to ensure the chroot environment contains all the
|
||||||
host-up), unless it's setup to be runnable inside chroot
|
files necessary for tinc to run correctly. Most importantly, for
|
||||||
environment.
|
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.
|
This option is not supported on all platforms.
|
||||||
'-U, --user=USER'
|
'-U, --user=USER'
|
||||||
|
@ -2150,6 +2143,9 @@ File: tinc.info, Node: tinc runtime options, Next: tinc environment variables,
|
||||||
daemon. If unspecified, the default is
|
daemon. If unspecified, the default is
|
||||||
'/var/run/tinc.NETNAME.pid'.
|
'/var/run/tinc.NETNAME.pid'.
|
||||||
|
|
||||||
|
'-b, --batch'
|
||||||
|
Don't ask for anything (non-interactive mode).
|
||||||
|
|
||||||
'--force'
|
'--force'
|
||||||
Force some commands to work despite warnings.
|
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
|
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
|
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
|
whose public key is known. If no FILENAME is given, the file is
|
||||||
read from standard input. If the verification is succesful, a copy
|
read from standard input. If the verification is successful, a
|
||||||
of the input with the signature removed is written to standard
|
copy of the input with the signature removed is written to standard
|
||||||
output, and the exit code will be zero. If the verification
|
output, and the exit code will be zero. If the verification
|
||||||
failed, nothing will be written to standard output, and the exit
|
failed, nothing will be written to standard output, and the exit
|
||||||
code will be non-zero.
|
code will be non-zero.
|
||||||
|
@ -2376,7 +2372,7 @@ Examples of changing the configuration using tinc:
|
||||||
tinc -n vpn init foo
|
tinc -n vpn init foo
|
||||||
tinc -n vpn add Subnet 192.168.1.0/24
|
tinc -n vpn add Subnet 192.168.1.0/24
|
||||||
tinc -n vpn add bar.Address bar.example.com
|
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
|
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>
|
<c>
|
||||||
Toggle between displaying current traffic rates (in packets and
|
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).
|
since the tinc daemon started).
|
||||||
|
|
||||||
<n>
|
<n>
|
||||||
|
@ -2528,7 +2524,8 @@ invite' command looks like this:
|
||||||
The file is basically a concatenation of several host config blocks.
|
The file is basically a concatenation of several host config blocks.
|
||||||
Each host config block starts with 'Name = ...'. Lines that look like
|
Each host config block starts with 'Name = ...'. Lines that look like
|
||||||
'#---#' are not important, it just makes it easier for humans to read
|
'#---#' 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.
|
The first host config block is always the one representing the invitee.
|
||||||
So the first Name statement determines the name that the invitee will
|
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
|
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
|
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 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:
|
recreates the default invitation file:
|
||||||
|
|
||||||
#!/bin/sh
|
#!/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
|
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
|
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
|
modes cannot be used on the following operating systems which don't have
|
||||||
a 'tap' style virtual network device: OpenBSD, NetBSD, Darwin and
|
a 'tap' style virtual network device: NetBSD, Darwin and Solaris.
|
||||||
Solaris.
|
|
||||||
|
|
||||||
|
|
||||||
File: tinc.info, Node: The meta-connection, Prev: The UDP tunnel, Up: The connection
|
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
|
We do not know of a security hole in the legacy protocol of tinc, but it
|
||||||
is not as strong as TLS or IPsec.
|
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
|
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
|
Peer-to-Peer Security (SPTPS), which aims to be as strong as TLS with
|
||||||
strongest cipher suites.
|
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
|
Cryptography is a hard thing to get right. We cannot make any
|
||||||
guarantees. Time, review and feedback are the only things that can
|
guarantees. Time, review and feedback are the only things that can
|
||||||
prove the security of any cryptographic product. If you wish to review
|
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
|
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::
|
* Interface configuration::
|
||||||
* Routes::
|
* Routes::
|
||||||
|
* Automatically starting tinc::
|
||||||
|
|
||||||
|
|
||||||
File: tinc.info, Node: Interface configuration, Next: Routes, Up: Platform specific information
|
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
|
Darwin (MacOS/X) 'ifconfig' INTERFACE 'inet6' ADDRESS 'prefixlen' PREFIXLENGTH
|
||||||
Windows 'netsh interface ipv6 add address' INTERFACE 'static' ADDRESS/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
|
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
|
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
|
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
|
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
|
9.2 Routes
|
||||||
==========
|
==========
|
||||||
|
@ -3295,6 +3302,72 @@ Solaris 'route add -inet6' NETWORK_ADDRESS'/'PREFIXLENGTH LOCAL_ADDRE
|
||||||
Darwin (MacOS/X) ?
|
Darwin (MacOS/X) ?
|
||||||
Windows 'netsh interface ipv6 add route' NETWORK ADDRESS/PREFIXLENGTH INTERFACE
|
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
|
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)
|
* ANS_KEY: The meta-protocol. (line 63)
|
||||||
* AutoConnect: Main configuration variables.
|
* AutoConnect: Main configuration variables.
|
||||||
(line 12)
|
(line 12)
|
||||||
|
* batch: tinc runtime options.
|
||||||
|
(line 18)
|
||||||
* binary package: Building and installing tinc.
|
* binary package: Building and installing tinc.
|
||||||
(line 9)
|
(line 9)
|
||||||
* BindToAddress: Main configuration variables.
|
* BindToAddress: Main configuration variables.
|
||||||
|
@ -3376,7 +3451,7 @@ Concept Index
|
||||||
* ClampMSS: Host configuration variables.
|
* ClampMSS: Host configuration variables.
|
||||||
(line 22)
|
(line 22)
|
||||||
* client: How connections work.
|
* client: How connections work.
|
||||||
(line 18)
|
(line 12)
|
||||||
* command line: Runtime options. (line 9)
|
* command line: Runtime options. (line 9)
|
||||||
* command line interface: Controlling tinc. (line 6)
|
* command line interface: Controlling tinc. (line 6)
|
||||||
* Compression: Host configuration variables.
|
* Compression: Host configuration variables.
|
||||||
|
@ -3422,7 +3497,7 @@ Concept Index
|
||||||
* exchange: tinc commands. (line 48)
|
* exchange: tinc commands. (line 48)
|
||||||
* exchange-all: tinc commands. (line 51)
|
* exchange-all: tinc commands. (line 51)
|
||||||
* exec: Main configuration variables.
|
* exec: Main configuration variables.
|
||||||
(line 365)
|
(line 373)
|
||||||
* ExperimentalProtocol: Main configuration variables.
|
* ExperimentalProtocol: Main configuration variables.
|
||||||
(line 185)
|
(line 185)
|
||||||
* export: tinc commands. (line 36)
|
* export: tinc commands. (line 36)
|
||||||
|
@ -3433,38 +3508,40 @@ Concept Index
|
||||||
(line 192)
|
(line 192)
|
||||||
* frame type: The UDP tunnel. (line 6)
|
* frame type: The UDP tunnel. (line 6)
|
||||||
* fsck: tinc commands. (line 160)
|
* fsck: tinc commands. (line 160)
|
||||||
|
* FWMark: Main configuration variables.
|
||||||
|
(line 214)
|
||||||
* generate-ed25519-keys: tinc commands. (line 86)
|
* generate-ed25519-keys: tinc commands. (line 86)
|
||||||
* generate-keys: tinc commands. (line 81)
|
* generate-keys: tinc commands. (line 81)
|
||||||
* generate-rsa-keys: tinc commands. (line 89)
|
* generate-rsa-keys: tinc commands. (line 89)
|
||||||
* get: tinc commands. (line 11)
|
* get: tinc commands. (line 11)
|
||||||
* graph: tinc commands. (line 108)
|
* graph: tinc commands. (line 108)
|
||||||
* Hostnames: Main configuration variables.
|
* Hostnames: Main configuration variables.
|
||||||
(line 212)
|
(line 220)
|
||||||
* http: Main configuration variables.
|
* http: Main configuration variables.
|
||||||
(line 362)
|
(line 370)
|
||||||
* hub: Main configuration variables.
|
* hub: Main configuration variables.
|
||||||
(line 280)
|
(line 288)
|
||||||
* ID: Legacy authentication protocol.
|
* ID: Legacy authentication protocol.
|
||||||
(line 6)
|
(line 6)
|
||||||
* Ifconfig: Invitation file format.
|
* Ifconfig: Invitation file format.
|
||||||
(line 35)
|
(line 36)
|
||||||
* import: tinc commands. (line 43)
|
* import: tinc commands. (line 43)
|
||||||
* IndirectData: Host configuration variables.
|
* IndirectData: Host configuration variables.
|
||||||
(line 40)
|
(line 40)
|
||||||
* info: tinc commands. (line 120)
|
* info: tinc commands. (line 120)
|
||||||
* init: tinc commands. (line 6)
|
* init: tinc commands. (line 6)
|
||||||
* Interface: Main configuration variables.
|
* Interface: Main configuration variables.
|
||||||
(line 223)
|
(line 231)
|
||||||
* INTERFACE: Scripts. (line 75)
|
* INTERFACE: Scripts. (line 75)
|
||||||
* InvitationExpire: Main configuration variables.
|
* InvitationExpire: Main configuration variables.
|
||||||
(line 285)
|
(line 293)
|
||||||
* INVITATION_FILE: Scripts. (line 98)
|
* INVITATION_FILE: Scripts. (line 98)
|
||||||
* INVITATION_URL: Scripts. (line 102)
|
* INVITATION_URL: Scripts. (line 102)
|
||||||
* invite: tinc commands. (line 54)
|
* invite: tinc commands. (line 54)
|
||||||
* IRC: Contact information. (line 9)
|
* IRC: Contact information. (line 9)
|
||||||
* join: tinc commands. (line 59)
|
* join: tinc commands. (line 59)
|
||||||
* KeyExpire: Main configuration variables.
|
* KeyExpire: Main configuration variables.
|
||||||
(line 288)
|
(line 296)
|
||||||
* KEY_CHANGED: The meta-protocol. (line 63)
|
* KEY_CHANGED: The meta-protocol. (line 63)
|
||||||
* legacy authentication protocol: Legacy authentication protocol.
|
* legacy authentication protocol: Legacy authentication protocol.
|
||||||
(line 6)
|
(line 6)
|
||||||
|
@ -3474,31 +3551,31 @@ Concept Index
|
||||||
* LibreSSL: LibreSSL/OpenSSL. (line 6)
|
* LibreSSL: LibreSSL/OpenSSL. (line 6)
|
||||||
* license: LibreSSL/OpenSSL. (line 38)
|
* license: LibreSSL/OpenSSL. (line 38)
|
||||||
* ListenAddress: Main configuration variables.
|
* ListenAddress: Main configuration variables.
|
||||||
(line 231)
|
(line 239)
|
||||||
* LocalDiscovery: Main configuration variables.
|
* LocalDiscovery: Main configuration variables.
|
||||||
(line 243)
|
(line 251)
|
||||||
* log: tinc commands. (line 130)
|
* log: tinc commands. (line 130)
|
||||||
* LogLevel: Main configuration variables.
|
* LogLevel: Main configuration variables.
|
||||||
(line 254)
|
(line 262)
|
||||||
* lzo: lzo. (line 6)
|
* LZO: LZO. (line 6)
|
||||||
* MACExpire: Main configuration variables.
|
* MACExpire: Main configuration variables.
|
||||||
(line 294)
|
(line 302)
|
||||||
* MACLength: Host configuration variables.
|
* MACLength: Host configuration variables.
|
||||||
(line 45)
|
(line 45)
|
||||||
* MaxConnectionBurst: Main configuration variables.
|
* MaxConnectionBurst: Main configuration variables.
|
||||||
(line 299)
|
(line 307)
|
||||||
* meta-protocol: The meta-connection. (line 18)
|
* meta-protocol: The meta-connection. (line 18)
|
||||||
* META_KEY: Legacy authentication protocol.
|
* META_KEY: Legacy authentication protocol.
|
||||||
(line 6)
|
(line 6)
|
||||||
* Mode: Main configuration variables.
|
* Mode: Main configuration variables.
|
||||||
(line 258)
|
(line 266)
|
||||||
* MTUInfoInterval: Host configuration variables.
|
* MTUInfoInterval: Host configuration variables.
|
||||||
(line 60)
|
(line 60)
|
||||||
* multicast: Main configuration variables.
|
* multicast: Main configuration variables.
|
||||||
(line 118)
|
(line 118)
|
||||||
* multiple networks: Multiple networks. (line 6)
|
* multiple networks: Multiple networks. (line 6)
|
||||||
* Name: Main configuration variables.
|
* Name: Main configuration variables.
|
||||||
(line 305)
|
(line 313)
|
||||||
* NAME: Scripts. (line 69)
|
* NAME: Scripts. (line 69)
|
||||||
* netmask: Network interfaces. (line 39)
|
* netmask: Network interfaces. (line 39)
|
||||||
* netname: Multiple networks. (line 6)
|
* netname: Multiple networks. (line 6)
|
||||||
|
@ -3517,9 +3594,9 @@ Concept Index
|
||||||
* pid: tinc commands. (line 78)
|
* pid: tinc commands. (line 78)
|
||||||
* PING: The meta-protocol. (line 88)
|
* PING: The meta-protocol. (line 88)
|
||||||
* PingInterval: Main configuration variables.
|
* PingInterval: Main configuration variables.
|
||||||
(line 316)
|
(line 324)
|
||||||
* PingTimeout: Main configuration variables.
|
* PingTimeout: Main configuration variables.
|
||||||
(line 320)
|
(line 328)
|
||||||
* platforms: Supported platforms. (line 6)
|
* platforms: Supported platforms. (line 6)
|
||||||
* PMTU: Host configuration variables.
|
* PMTU: Host configuration variables.
|
||||||
(line 52)
|
(line 52)
|
||||||
|
@ -3530,17 +3607,17 @@ Concept Index
|
||||||
(line 65)
|
(line 65)
|
||||||
* port numbers: Other files. (line 17)
|
* port numbers: Other files. (line 17)
|
||||||
* PriorityInheritance: Main configuration variables.
|
* PriorityInheritance: Main configuration variables.
|
||||||
(line 326)
|
(line 334)
|
||||||
* private: Virtual Private Networks.
|
* private: Virtual Private Networks.
|
||||||
(line 10)
|
(line 10)
|
||||||
* PrivateKey: Main configuration variables.
|
* PrivateKey: Main configuration variables.
|
||||||
(line 331)
|
(line 339)
|
||||||
* PrivateKeyFile: Main configuration variables.
|
* PrivateKeyFile: Main configuration variables.
|
||||||
(line 337)
|
(line 345)
|
||||||
* ProcessPriority: Main configuration variables.
|
* ProcessPriority: Main configuration variables.
|
||||||
(line 342)
|
(line 350)
|
||||||
* Proxy: Main configuration variables.
|
* Proxy: Main configuration variables.
|
||||||
(line 347)
|
(line 355)
|
||||||
* PublicKey: Host configuration variables.
|
* PublicKey: Host configuration variables.
|
||||||
(line 69)
|
(line 69)
|
||||||
* PublicKeyFile: Host configuration variables.
|
* PublicKeyFile: Host configuration variables.
|
||||||
|
@ -3553,40 +3630,41 @@ Concept Index
|
||||||
* REMOTEADDRESS: Scripts. (line 84)
|
* REMOTEADDRESS: Scripts. (line 84)
|
||||||
* REMOTEPORT: Scripts. (line 87)
|
* REMOTEPORT: Scripts. (line 87)
|
||||||
* ReplayWindow: Main configuration variables.
|
* ReplayWindow: Main configuration variables.
|
||||||
(line 370)
|
(line 378)
|
||||||
* requirements: Libraries. (line 6)
|
* requirements: Libraries. (line 6)
|
||||||
* REQ_KEY: The meta-protocol. (line 63)
|
* REQ_KEY: The meta-protocol. (line 63)
|
||||||
* restart: tinc commands. (line 70)
|
* restart: tinc commands. (line 70)
|
||||||
* retry: tinc commands. (line 135)
|
* retry: tinc commands. (line 135)
|
||||||
* Route: Invitation file format.
|
* Route: Invitation file format.
|
||||||
(line 51)
|
(line 52)
|
||||||
* router: Main configuration variables.
|
* router: Main configuration variables.
|
||||||
(line 261)
|
(line 269)
|
||||||
* runtime options: Runtime options. (line 9)
|
* runtime options: Runtime options. (line 9)
|
||||||
* scalability: tinc. (line 19)
|
* scalability: tinc. (line 19)
|
||||||
* scripts: Scripts. (line 6)
|
* scripts: Scripts. (line 6)
|
||||||
* server: How connections work.
|
* server: How connections work.
|
||||||
(line 18)
|
(line 12)
|
||||||
* set: tinc commands. (line 16)
|
* set: tinc commands. (line 16)
|
||||||
* shell: Controlling tinc. (line 11)
|
* shell: Controlling tinc. (line 11)
|
||||||
* sign: tinc commands. (line 172)
|
* sign: tinc commands. (line 172)
|
||||||
* signals: Signals. (line 6)
|
* signals: Signals. (line 6)
|
||||||
* socks4: Main configuration variables.
|
* socks4: Main configuration variables.
|
||||||
(line 351)
|
(line 359)
|
||||||
* socks5: Main configuration variables.
|
* socks5: Main configuration variables.
|
||||||
(line 356)
|
(line 364)
|
||||||
* SPTPS: Simple Peer-to-Peer Security.
|
* SPTPS: Simple Peer-to-Peer Security.
|
||||||
(line 6)
|
(line 6)
|
||||||
* start: tinc commands. (line 64)
|
* start: tinc commands. (line 64)
|
||||||
* stop: tinc commands. (line 67)
|
* stop: tinc commands. (line 67)
|
||||||
* StrictSubnets: Main configuration variables.
|
* StrictSubnets: Main configuration variables.
|
||||||
(line 381)
|
(line 389)
|
||||||
* Subnet: Host configuration variables.
|
* Subnet: Host configuration variables.
|
||||||
(line 84)
|
(line 84)
|
||||||
* SUBNET: Scripts. (line 91)
|
* SUBNET: Scripts. (line 91)
|
||||||
* SVPN: Security. (line 11)
|
* SVPN: Security. (line 11)
|
||||||
* switch: Main configuration variables.
|
* switch: Main configuration variables.
|
||||||
(line 269)
|
(line 277)
|
||||||
|
* systemd: Linux. (line 6)
|
||||||
* TCP: The meta-connection. (line 10)
|
* TCP: The meta-connection. (line 10)
|
||||||
* TCPonly: Host configuration variables.
|
* TCPonly: Host configuration variables.
|
||||||
(line 113)
|
(line 113)
|
||||||
|
@ -3602,36 +3680,36 @@ Concept Index
|
||||||
* tunifhead: Main configuration variables.
|
* tunifhead: Main configuration variables.
|
||||||
(line 158)
|
(line 158)
|
||||||
* TunnelServer: Main configuration variables.
|
* TunnelServer: Main configuration variables.
|
||||||
(line 388)
|
(line 396)
|
||||||
* tunnohead: Main configuration variables.
|
* tunnohead: Main configuration variables.
|
||||||
(line 152)
|
(line 152)
|
||||||
* UDP: The UDP tunnel. (line 30)
|
* UDP: The UDP tunnel. (line 30)
|
||||||
* UDP <1>: Encryption of network packets.
|
* UDP <1>: Encryption of network packets.
|
||||||
(line 11)
|
(line 11)
|
||||||
* UDPDiscoveryInterval: Main configuration variables.
|
* UDPDiscoveryInterval: Main configuration variables.
|
||||||
(line 408)
|
(line 416)
|
||||||
* UDPDiscoveryKeepaliveInterval: Main configuration variables.
|
* UDPDiscoveryKeepaliveInterval: Main configuration variables.
|
||||||
(line 402)
|
(line 410)
|
||||||
* UDPDiscoveryTimeout: Main configuration variables.
|
* UDPDiscoveryTimeout: Main configuration variables.
|
||||||
(line 412)
|
(line 420)
|
||||||
* UDPDiscovey: Main configuration variables.
|
* UDPDiscovey: Main configuration variables.
|
||||||
(line 395)
|
(line 403)
|
||||||
* UDPInfoInterval: Main configuration variables.
|
* UDPInfoInterval: Main configuration variables.
|
||||||
(line 417)
|
(line 425)
|
||||||
* UDPRcvBuf: Main configuration variables.
|
* UDPRcvBuf: Main configuration variables.
|
||||||
(line 421)
|
(line 429)
|
||||||
* UDPSndBuf: Main configuration variables.
|
* UDPSndBuf: Main configuration variables.
|
||||||
(line 427)
|
(line 435)
|
||||||
* UML: Main configuration variables.
|
* UML: Main configuration variables.
|
||||||
(line 134)
|
(line 134)
|
||||||
* Universal tun/tap: Configuration of Linux kernels.
|
* Universal tun/tap: Configuration of Linux kernels.
|
||||||
(line 6)
|
(line 6)
|
||||||
* UPnP: Main configuration variables.
|
* UPnP: Main configuration variables.
|
||||||
(line 433)
|
(line 441)
|
||||||
* UPnPDiscoverWait: Main configuration variables.
|
* UPnPDiscoverWait: Main configuration variables.
|
||||||
(line 444)
|
(line 452)
|
||||||
* UPnPRefreshPeriod: Main configuration variables.
|
* UPnPRefreshPeriod: Main configuration variables.
|
||||||
(line 448)
|
(line 456)
|
||||||
* utun: Main configuration variables.
|
* utun: Main configuration variables.
|
||||||
(line 165)
|
(line 165)
|
||||||
* VDE: Main configuration variables.
|
* VDE: Main configuration variables.
|
||||||
|
@ -3652,78 +3730,82 @@ Concept Index
|
||||||
|
|
||||||
|
|
||||||
Tag Table:
|
Tag Table:
|
||||||
Node: Top824
|
Node: Top808
|
||||||
Node: Introduction1160
|
Node: Introduction1144
|
||||||
Node: Virtual Private Networks1964
|
Node: Virtual Private Networks1948
|
||||||
Node: tinc3676
|
Node: tinc3660
|
||||||
Node: Supported platforms5188
|
Node: Supported platforms5173
|
||||||
Node: Preparations5885
|
Node: Preparations5870
|
||||||
Node: Configuring the kernel6141
|
Node: Configuring the kernel6126
|
||||||
Node: Configuration of Linux kernels6550
|
Node: Configuration of Linux kernels6535
|
||||||
Node: Configuration of FreeBSD kernels7399
|
Node: Configuration of FreeBSD kernels7384
|
||||||
Node: Configuration of OpenBSD kernels7864
|
Node: Configuration of OpenBSD kernels7849
|
||||||
Node: Configuration of NetBSD kernels8221
|
Node: Configuration of NetBSD kernels8206
|
||||||
Node: Configuration of Solaris kernels8623
|
Node: Configuration of Solaris kernels8608
|
||||||
Node: Configuration of Darwin (MacOS/X) kernels9285
|
Node: Configuration of Darwin (MacOS/X) kernels9270
|
||||||
Node: Configuration of Windows10098
|
Node: Configuration of Windows10083
|
||||||
Node: Libraries10637
|
Node: Libraries10622
|
||||||
Node: LibreSSL/OpenSSL11094
|
Node: LibreSSL/OpenSSL11079
|
||||||
Node: zlib13620
|
Node: zlib13607
|
||||||
Node: lzo14642
|
Node: LZO14627
|
||||||
Node: libcurses15633
|
Node: libcurses15619
|
||||||
Node: libreadline16543
|
Node: libreadline16531
|
||||||
Node: Installation17480
|
Node: Installation17470
|
||||||
Node: Building and installing tinc18384
|
Node: Building and installing tinc18374
|
||||||
Node: Darwin (MacOS/X) build environment19040
|
Node: Darwin (MacOS/X) build environment19030
|
||||||
Node: Cygwin (Windows) build environment19599
|
Node: Cygwin (Windows) build environment19589
|
||||||
Node: MinGW (Windows) build environment20184
|
Node: MinGW (Windows) build environment20174
|
||||||
Node: System files20772
|
Node: System files20762
|
||||||
Node: Device files21037
|
Node: Device files21027
|
||||||
Node: Other files21450
|
Node: Other files21440
|
||||||
Node: Configuration22063
|
Node: Configuration22053
|
||||||
Node: Configuration introduction22350
|
Node: Configuration introduction22340
|
||||||
Node: Multiple networks23871
|
Node: Multiple networks23862
|
||||||
Node: How connections work25238
|
Node: How connections work25230
|
||||||
Node: Configuration files27799
|
Node: Configuration files27494
|
||||||
Node: Main configuration variables29431
|
Node: Main configuration variables29125
|
||||||
Node: Host configuration variables50412
|
Node: Host configuration variables50523
|
||||||
Node: Scripts56482
|
Node: Scripts56595
|
||||||
Node: How to configure60382
|
Node: How to configure60495
|
||||||
Node: Network interfaces64866
|
Node: Network interfaces64406
|
||||||
Node: Example configuration67245
|
Node: Example configuration66785
|
||||||
Node: Running tinc72344
|
Node: Running tinc71726
|
||||||
Node: Runtime options72931
|
Node: Runtime options72313
|
||||||
Node: Signals75791
|
Node: Signals75581
|
||||||
Node: Debug levels76640
|
Node: Debug levels76430
|
||||||
Node: Solving problems77576
|
Node: Solving problems77366
|
||||||
Node: Error messages79002
|
Node: Error messages78792
|
||||||
Node: Sending bug reports83319
|
Node: Sending bug reports83109
|
||||||
Node: Controlling tinc84266
|
Node: Controlling tinc84056
|
||||||
Node: tinc runtime options85002
|
Node: tinc runtime options84792
|
||||||
Node: tinc environment variables85751
|
Node: tinc environment variables85608
|
||||||
Node: tinc commands86080
|
Node: tinc commands85937
|
||||||
Node: tinc examples92938
|
Node: tinc examples92796
|
||||||
Node: tinc top93500
|
Node: tinc top93356
|
||||||
Node: Invitations95085
|
Node: Invitations94940
|
||||||
Node: How invitations work95748
|
Node: How invitations work95603
|
||||||
Node: Invitation file format98041
|
Node: Invitation file format97896
|
||||||
Node: Writing an invitation-created script100966
|
Node: Writing an invitation-created script100907
|
||||||
Node: Technical information102028
|
Node: Technical information101970
|
||||||
Node: The connection102258
|
Node: The connection102200
|
||||||
Node: The UDP tunnel102570
|
Node: The UDP tunnel102512
|
||||||
Node: The meta-connection105615
|
Node: The meta-connection105548
|
||||||
Node: The meta-protocol107073
|
Node: The meta-protocol107006
|
||||||
Node: Security112056
|
Node: Security111989
|
||||||
Node: Legacy authentication protocol113393
|
Node: Legacy authentication protocol113326
|
||||||
Node: Simple Peer-to-Peer Security118010
|
Node: Simple Peer-to-Peer Security117943
|
||||||
Node: Encryption of network packets123655
|
Node: Encryption of network packets123588
|
||||||
Node: Security issues126293
|
Node: Security issues126226
|
||||||
Node: Platform specific information128040
|
Node: Platform specific information128818
|
||||||
Node: Interface configuration128268
|
Node: Interface configuration129078
|
||||||
Node: Routes130709
|
Node: Routes131348
|
||||||
Node: About us132620
|
Node: Automatically starting tinc133295
|
||||||
Node: Contact information132797
|
Node: Linux133518
|
||||||
Node: Authors133200
|
Node: Windows134730
|
||||||
Node: Concept Index133604
|
Node: Other platforms135274
|
||||||
|
Node: About us135556
|
||||||
|
Node: Contact information135733
|
||||||
|
Node: Authors136136
|
||||||
|
Node: Concept Index136540
|
||||||
|
|
||||||
End Tag Table
|
End Tag Table
|
||||||
|
|
238
doc/tinc.texi
238
doc/tinc.texi
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
This is the info manual for @value{PACKAGE} version @value{VERSION}, a Virtual Private Network daemon.
|
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
|
Guus Sliepen <guus@@tinc-vpn.org> and
|
||||||
Wessel Dankers <wsl@@tinc-vpn.org>.
|
Wessel Dankers <wsl@@tinc-vpn.org>.
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ permission notice identical to this one.
|
||||||
@vskip 0pt plus 1filll
|
@vskip 0pt plus 1filll
|
||||||
This is the info manual for @value{PACKAGE} version @value{VERSION}, a Virtual Private Network daemon.
|
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
|
Guus Sliepen <guus@@tinc-vpn.org> and
|
||||||
Wessel Dankers <wsl@@tinc-vpn.org>.
|
Wessel Dankers <wsl@@tinc-vpn.org>.
|
||||||
|
|
||||||
|
@ -331,14 +331,14 @@ as explained in the rest of the documentation.
|
||||||
@cindex requirements
|
@cindex requirements
|
||||||
@cindex libraries
|
@cindex libraries
|
||||||
Before you can configure or build tinc, you need to have the LibreSSL or OpenSSL, zlib,
|
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
|
configure tinc without having them installed, configure will give you an error
|
||||||
message, and stop.
|
message, and stop.
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
* LibreSSL/OpenSSL::
|
* LibreSSL/OpenSSL::
|
||||||
* zlib::
|
* zlib::
|
||||||
* lzo::
|
* LZO::
|
||||||
* libcurses::
|
* libcurses::
|
||||||
* libreadline::
|
* libreadline::
|
||||||
@end menu
|
@end menu
|
||||||
|
@ -353,7 +353,7 @@ message, and stop.
|
||||||
For all cryptography-related functions, tinc uses the functions provided
|
For all cryptography-related functions, tinc uses the functions provided
|
||||||
by the LibreSSL or the OpenSSL library.
|
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
|
tinc for build. Support for running tinc with other cryptographic libraries
|
||||||
installed @emph{may} be added in the future.
|
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
|
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
|
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.
|
configure, build and install this package are included within the package.
|
||||||
Please make sure you build development and runtime libraries (which is the
|
Please make sure you build development and runtime libraries (which is the
|
||||||
default).
|
default).
|
||||||
|
@ -419,7 +419,7 @@ Markus F.X.J. Oberhumer
|
||||||
For the optional compression of UDP packets, tinc uses the functions provided
|
For the optional compression of UDP packets, tinc uses the functions provided
|
||||||
by the zlib library.
|
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
|
configure script. You can either install the zlib library, or disable support
|
||||||
for zlib compression by using the "--disable-zlib" option when running the
|
for zlib compression by using the "--disable-zlib" option when running the
|
||||||
configure script. Note that if you disable support for zlib, the resulting
|
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.
|
of this package.
|
||||||
|
|
||||||
If you have to install zlib manually, you can get the source code
|
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
|
build and install this package are included within the package. Please
|
||||||
make sure you build development and runtime libraries (which is the
|
make sure you build development and runtime libraries (which is the
|
||||||
default).
|
default).
|
||||||
|
|
||||||
|
|
||||||
@c ==================================================================
|
@c ==================================================================
|
||||||
@node lzo
|
@node LZO
|
||||||
@subsection lzo
|
@subsection LZO
|
||||||
|
|
||||||
@cindex lzo
|
@cindex LZO
|
||||||
Another form of compression is offered using the LZO library.
|
Another form of compression is offered using the LZO library.
|
||||||
|
|
||||||
If this library is not installed, you wil get an error when 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
|
configure script. You can either install the LZO library, or disable support
|
||||||
for LZO compression by using the "--disable-lzo" option when running the
|
for LZO compression by using the "--disable-lzo" option when running the
|
||||||
configure script. Note that if you disable support for LZO, the resulting
|
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
|
available. Make sure you install the development AND runtime versions
|
||||||
of this package.
|
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,
|
from @url{https://www.oberhumer.com/opensource/lzo/}. Instructions on how to configure,
|
||||||
build and install this package are included within the package. Please
|
build and install this package are included within the package. Please
|
||||||
make sure you build development and runtime libraries (which is the
|
make sure you build development and runtime libraries (which is the
|
||||||
|
@ -467,15 +467,15 @@ default).
|
||||||
@cindex libcurses
|
@cindex libcurses
|
||||||
For the "tinc top" command, tinc requires a curses library.
|
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
|
configure script. You can either install a suitable curses library, or disable
|
||||||
all functionality that depends on a curses library by using the
|
all functionality that depends on a curses library by using the
|
||||||
"--disable-curses" option when running the configure script.
|
"--disable-curses" option when running the configure script.
|
||||||
|
|
||||||
There are several curses libraries. It is recommended that you install
|
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.
|
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.
|
is recommended if you want to compile tinc for Windows.
|
||||||
|
|
||||||
You can use your operating system's package manager to install this if
|
You can use your operating system's package manager to install this if
|
||||||
|
@ -490,7 +490,7 @@ of this package.
|
||||||
@cindex libreadline
|
@cindex libreadline
|
||||||
For the "tinc" command's shell functionality, tinc uses the readline library.
|
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
|
configure script. You can either install a suitable readline library, or
|
||||||
disable all functionality that depends on a readline library by using the
|
disable all functionality that depends on a readline library by using the
|
||||||
"--disable-readline" option when running the configure script.
|
"--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.
|
of this package.
|
||||||
|
|
||||||
If you have to install libreadline manually, you can get the source code from
|
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
|
build and install this package are included within the package. Please make
|
||||||
sure you build development and runtime libraries (which is the default).
|
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.
|
Make sure you have an adequate understanding of networks in general.
|
||||||
@cindex Network Administrators Guide
|
@cindex Network Administrators Guide
|
||||||
A good resource on networking is the
|
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,
|
If you have everything clearly pictured in your mind,
|
||||||
proceed in the following order:
|
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,
|
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.
|
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,
|
This means that you call tinc with the -n argument,
|
||||||
which will specify the netname.
|
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
|
When tinc starts up, it parses the command-line options and then
|
||||||
reads in the configuration file tinc.conf.
|
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 then start listening for incoming connection from other daemons,
|
||||||
it will try to connect to those other daemons.
|
and will by default also automatically try to connect to known peers.
|
||||||
Whether this succeeds or not and whether `ConnectTo' is specified or not,
|
By default, tinc will try to keep at least 3 working meta-connections alive at all times.
|
||||||
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.
|
|
||||||
|
|
||||||
@cindex client
|
@cindex client
|
||||||
@cindex server
|
@cindex server
|
||||||
There is no real distinction between a server and a client in tinc.
|
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,
|
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 specify such a value as a client.
|
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.
|
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.
|
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 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
|
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.
|
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}/tinc.conf} and at least one other file in the directory
|
||||||
@file{@value{sysconfdir}/tinc/@var{netname}/hosts/}.
|
@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.
|
any .conf file will be read.
|
||||||
|
|
||||||
These file consists of comments (lines started with a #) or assignments
|
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.
|
both IPv4 and IPv6 or just IPv6 listening sockets will be created.
|
||||||
|
|
||||||
@cindex AutoConnect
|
@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,
|
If set to yes, tinc will automatically set up meta connections to other nodes,
|
||||||
without requiring @var{ConnectTo} variables.
|
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
|
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).
|
(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,
|
tinc won't try to connect to other daemons at all,
|
||||||
and will instead just listen for incoming connections.
|
and will instead just listen for incoming connections.
|
||||||
|
|
||||||
|
@ -967,7 +960,7 @@ Packets received for the local node are written to it.
|
||||||
@cindex UML
|
@cindex UML
|
||||||
@item uml (not compiled in by default)
|
@item uml (not compiled in by default)
|
||||||
Create a UNIX socket with the filename specified by
|
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.
|
if not specified.
|
||||||
Tinc will wait for a User Mode Linux instance to connect to this socket.
|
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)
|
@item vde (not compiled in by default)
|
||||||
Uses the libvdeplug library to connect to a Virtual Distributed Ethernet switch,
|
Uses the libvdeplug library to connect to a Virtual Distributed Ethernet switch,
|
||||||
using the UNIX socket specified by
|
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.
|
if not specified.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
@ -1048,11 +1041,19 @@ Incoming packets that are meant for another node are forwarded by tinc internall
|
||||||
This is the default mode, and unless you really know you need another forwarding mode, don't change it.
|
This is the default mode, and unless you really know you need another forwarding mode, don't change it.
|
||||||
|
|
||||||
@item kernel
|
@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,
|
This is less efficient, but allows the kernel to apply its routing and firewall rules on them,
|
||||||
and can also help debugging.
|
and can also help debugging.
|
||||||
|
Incoming packets using the SPTPS protocol are dropped, since they are end-to-end encrypted.
|
||||||
@end table
|
@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
|
@cindex Hostnames
|
||||||
@item Hostnames = <yes|no> (no)
|
@item Hostnames = <yes|no> (no)
|
||||||
This option selects whether IP addresses (both real and on the VPN)
|
This option selects whether IP addresses (both real and on the VPN)
|
||||||
|
@ -1179,7 +1180,7 @@ will be inherited by the UDP packets that are sent out.
|
||||||
@item PrivateKey = <@var{key}> [obsolete]
|
@item PrivateKey = <@var{key}> [obsolete]
|
||||||
This is the RSA private key for tinc. However, for safety reasons it is
|
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
|
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
|
@cindex PrivateKeyFile
|
||||||
@item PrivateKeyFile = <@var{path}> (@file{@value{sysconfdir}/tinc/@var{netname}/rsa_key.priv})
|
@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)
|
@item Compression = <@var{level}> (0)
|
||||||
This option sets the level of compression used for UDP packets.
|
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),
|
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
|
@cindex Digest
|
||||||
@item Digest = <@var{digest}> (sha1)
|
@item Digest = <@var{digest}> (sha1)
|
||||||
|
@ -1396,7 +1397,7 @@ connection with that host.
|
||||||
@cindex Subnet
|
@cindex Subnet
|
||||||
@item Subnet = <@var{address}[/@var{prefixlength}[#@var{weight}]]>
|
@item Subnet = <@var{address}[/@var{prefixlength}[#@var{weight}]]>
|
||||||
The subnet which this tinc daemon will serve.
|
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,
|
If the packet matches a subnet,
|
||||||
it will be sent to the daemon who has this subnet in his host configuration file.
|
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.
|
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
|
tinc -n @var{netname} add address foo.example.org
|
||||||
@end example
|
@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.
|
@subsubheading Step 2. Exchanging configuration files.
|
||||||
|
|
||||||
If your daemon has a ConnectTo = bar statement in its @file{tinc.conf} file,
|
In order for two tinc daemons to be able to connect to each other,
|
||||||
or if bar has a ConnectTo your daemon, then you both need each other's host configuration files.
|
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}.
|
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
|
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):
|
(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
|
| tinc -n @var{netname} import
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
You should repeat this for all nodes you ConnectTo, or which ConnectTo you.
|
You can repeat this for a few other nodes as well.
|
||||||
However, remember that you do not need to ConnectTo all nodes in the VPN;
|
It is not necessary to manually exchange host config files between all nodes;
|
||||||
it is only necessary to create one or a few meta-connections,
|
after the initial connections are made tinc will learn about all the other nodes in the VPN,
|
||||||
after the connections are made tinc will learn about all the other nodes in the VPN,
|
|
||||||
and will automatically make other connections as necessary.
|
and will automatically make other connections as necessary.
|
||||||
|
|
||||||
|
|
||||||
|
@ -1817,12 +1805,10 @@ and in @file{@value{sysconfdir}/tinc/company/tinc.conf}:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
Name = BranchB
|
Name = BranchB
|
||||||
ConnectTo = BranchA
|
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
Note here that the internal address (on eth0) doesn't have to be the
|
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
|
same as on the VPN interface.
|
||||||
always try to connect to BranchA.
|
|
||||||
|
|
||||||
On all hosts, in @file{@value{sysconfdir}/tinc/company/hosts/BranchB}:
|
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
|
@example
|
||||||
Name = BranchC
|
Name = BranchC
|
||||||
ConnectTo = BranchA
|
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
C already has another daemon that runs on port 655, so they have to
|
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
|
@example
|
||||||
Name = BranchD
|
Name = BranchD
|
||||||
ConnectTo = BranchC
|
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
D will be connecting to C, which has a tincd running for this network on
|
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}
|
@item --pidfile=@var{filename}
|
||||||
Store a cookie in @var{filename} which allows tinc to authenticate.
|
Store a cookie in @var{filename} which allows tinc to authenticate.
|
||||||
If unspecified, the default is
|
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}
|
@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}.
|
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.
|
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}.
|
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
|
@item --bypass-security
|
||||||
Disables encryption and authentication.
|
Disables encryption and authentication.
|
||||||
Only useful for debugging.
|
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
|
The chroot is performed after all the initialization is done, after
|
||||||
writing pid files and opening network sockets.
|
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),
|
You will need to ensure the chroot environment contains all the files necessary
|
||||||
unless it's setup to be runnable inside chroot environment.
|
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.
|
This option is not supported on all platforms.
|
||||||
@item -U, --user=@var{user}
|
@item -U, --user=@var{user}
|
||||||
|
@ -2295,7 +2286,11 @@ Use configuration for net @var{netname}. @xref{Multiple networks}.
|
||||||
@item --pidfile=@var{filename}
|
@item --pidfile=@var{filename}
|
||||||
Use the cookie from @var{filename} to authenticate with a running tinc daemon.
|
Use the cookie from @var{filename} to authenticate with a running tinc daemon.
|
||||||
If unspecified, the default is
|
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
|
@item --force
|
||||||
Force some commands to work despite warnings.
|
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 can be "." to check against the local node's public key,
|
||||||
or "*" to allow a signature from any node whose public key is known.
|
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 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.
|
If the verification failed, nothing will be written to standard output, and the exit code will be non-zero.
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
@ -2546,7 +2541,7 @@ Examples of changing the configuration using tinc:
|
||||||
tinc -n vpn init foo
|
tinc -n vpn init foo
|
||||||
tinc -n vpn add Subnet 192.168.1.0/24
|
tinc -n vpn add Subnet 192.168.1.0/24
|
||||||
tinc -n vpn add bar.Address bar.example.com
|
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
|
tinc -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@@example.com
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
|
@ -2571,7 +2566,7 @@ Intervals lower than 0.1 seconds are not allowed.
|
||||||
|
|
||||||
@item c
|
@item c
|
||||||
Toggle between displaying current traffic rates (in packets and bytes per second)
|
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
|
@item n
|
||||||
Sort the list of nodes by name.
|
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
|
The file is basically a concatenation of several host config blocks. Each host
|
||||||
config block starts with @code{Name = ...}. Lines that look like @code{#---#}
|
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.
|
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
|
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
|
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
|
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
|
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
|
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
|
@example
|
||||||
#!/bin/sh
|
#!/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.
|
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,
|
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:
|
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 ==================================================================
|
@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
|
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.
|
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,
|
The Sweet32 attack affects versions of tinc prior to 1.0.30.
|
||||||
which aims to be as strong as TLS with one of the strongest cipher suites.
|
|
||||||
|
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
|
Cryptography is a hard thing to get right. We cannot make any
|
||||||
guarantees. Time, review and feedback are the only things that can
|
guarantees. Time, review and feedback are the only things that can
|
||||||
prove the security of any cryptographic product. If you wish to review
|
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 ==================================================================
|
@c ==================================================================
|
||||||
|
@ -3394,6 +3405,7 @@ tinc or give us feedback, you are stronly encouraged to do so.
|
||||||
@menu
|
@menu
|
||||||
* Interface configuration::
|
* Interface configuration::
|
||||||
* Routes::
|
* Routes::
|
||||||
|
* Automatically starting tinc::
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@c ==================================================================
|
@c ==================================================================
|
||||||
|
@ -3450,13 +3462,6 @@ For IPv6 addresses:
|
||||||
@tab @code{netsh interface ipv6 add address} @var{interface} @code{static} @var{address}/@var{prefixlength}
|
@tab @code{netsh interface ipv6 add address} @var{interface} @code{static} @var{address}/@var{prefixlength}
|
||||||
@end multitable
|
@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
|
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.
|
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
|
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}
|
@tab @code{netsh interface ipv6 add route} @var{network address}/@var{prefixlength} @var{interface}
|
||||||
@end multitable
|
@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 ==================================================================
|
@c ==================================================================
|
||||||
@node About us
|
@node About us
|
||||||
|
|
|
@ -100,7 +100,7 @@ to authenticate.
|
||||||
If
|
If
|
||||||
.Ar FILE
|
.Ar FILE
|
||||||
is omitted, the default is
|
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
|
.It Fl -bypass-security
|
||||||
Disables encryption and authentication of the meta protocol.
|
Disables encryption and authentication of the meta protocol.
|
||||||
Only useful for debugging.
|
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.
|
Directory containing the configuration files tinc uses.
|
||||||
For more information, see
|
For more information, see
|
||||||
.Xr tinc.conf 5 .
|
.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
|
The PID of the currently running
|
||||||
.Nm
|
.Nm
|
||||||
is stored in this file.
|
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 PACKAGE @PACKAGE@
|
||||||
@set sysconfdir @sysconfdir@
|
@set sysconfdir @sysconfdir@
|
||||||
@set localstatedir @localstatedir@
|
@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
|
#!/bin/sh
|
||||||
# install - install a program, script, or datafile
|
# 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
|
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||||
|
@ -271,15 +271,18 @@ do
|
||||||
fi
|
fi
|
||||||
dst=$dst_arg
|
dst=$dst_arg
|
||||||
|
|
||||||
# If destination is a directory, append the input filename; won't work
|
# If destination is a directory, append the input filename.
|
||||||
# if double slashes aren't ignored.
|
|
||||||
if test -d "$dst"; then
|
if test -d "$dst"; then
|
||||||
if test "$is_target_a_directory" = never; then
|
if test "$is_target_a_directory" = never; then
|
||||||
echo "$0: $dst_arg: Is a directory" >&2
|
echo "$0: $dst_arg: Is a directory" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
dstdir=$dst
|
dstdir=$dst
|
||||||
dst=$dstdir/`basename "$src"`
|
dstbase=`basename "$src"`
|
||||||
|
case $dst in
|
||||||
|
*/) dst=$dst$dstbase;;
|
||||||
|
*) dst=$dst/$dstbase;;
|
||||||
|
esac
|
||||||
dstdir_status=0
|
dstdir_status=0
|
||||||
else
|
else
|
||||||
dstdir=`dirname "$dst"`
|
dstdir=`dirname "$dst"`
|
||||||
|
@ -288,6 +291,11 @@ do
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
case $dstdir in
|
||||||
|
*/) dstdirslash=$dstdir;;
|
||||||
|
*) dstdirslash=$dstdir/;;
|
||||||
|
esac
|
||||||
|
|
||||||
obsolete_mkdir_used=false
|
obsolete_mkdir_used=false
|
||||||
|
|
||||||
if test $dstdir_status != 0; then
|
if test $dstdir_status != 0; then
|
||||||
|
@ -324,14 +332,16 @@ do
|
||||||
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
|
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
# $RANDOM is not portable (e.g. dash); use it when possible to
|
# Note that $RANDOM variable is not portable (e.g. dash); Use it
|
||||||
# lower collision chance
|
# here however when possible just to lower collision chance.
|
||||||
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
|
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
|
||||||
|
|
||||||
trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
|
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
|
# Because "mkdir -p" follows existing symlinks and we likely work
|
||||||
# create the $tmpdir first (and fail if unsuccessful) to make sure
|
# directly in world-writeable /tmp, make sure that the '$tmpdir'
|
||||||
# that nobody tries to guess the $tmpdir name.
|
# directory is successfully created first before we actually test
|
||||||
|
# 'mkdir -p' feature.
|
||||||
if (umask $mkdir_umask &&
|
if (umask $mkdir_umask &&
|
||||||
$mkdirprog $mkdir_mode "$tmpdir" &&
|
$mkdirprog $mkdir_mode "$tmpdir" &&
|
||||||
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
|
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
|
||||||
|
@ -434,8 +444,8 @@ do
|
||||||
else
|
else
|
||||||
|
|
||||||
# Make a couple of temp file names in the proper directory.
|
# Make a couple of temp file names in the proper directory.
|
||||||
dsttmp=$dstdir/_inst.$$_
|
dsttmp=${dstdirslash}_inst.$$_
|
||||||
rmtmp=$dstdir/_rm.$$_
|
rmtmp=${dstdirslash}_rm.$$_
|
||||||
|
|
||||||
# Trap to clean up those temp files at exit.
|
# Trap to clean up those temp files at exit.
|
||||||
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
||||||
|
@ -500,9 +510,9 @@ do
|
||||||
done
|
done
|
||||||
|
|
||||||
# Local variables:
|
# Local variables:
|
||||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
# eval: (add-hook 'before-save-hook 'time-stamp)
|
||||||
# time-stamp-start: "scriptversion="
|
# time-stamp-start: "scriptversion="
|
||||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
# time-stamp-time-zone: "UTC"
|
# time-stamp-time-zone: "UTC0"
|
||||||
# time-stamp-end: "; # UTC"
|
# time-stamp-end: "; # UTC"
|
||||||
# End:
|
# 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,
|
AC_CHECK_LIB(ncurses, initscr,
|
||||||
[CURSES_LIBS="-lncurses"],
|
[CURSES_LIBS="-lncurses"; AC_CHECK_LIB(tinfo, wtimeout, [CURSES_LIBS+=" -ltinfo"], [])],
|
||||||
[AC_CHECK_LIB(curses, initscr,
|
[AC_CHECK_LIB(curses, initscr,
|
||||||
[CURSES_LIBS="-lcurses"],
|
[CURSES_LIBS="-lcurses"],
|
||||||
[AC_MSG_ERROR("curses libraries not found.")]
|
[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_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],
|
[AC_MSG_ERROR([Missing LibreSSL/OpenSSL functionality, make sure you have installed the latest version.]); break],
|
||||||
[#include <openssl/evp.h>]
|
[#include <openssl/evp.h>]
|
||||||
)
|
)
|
||||||
|
|
||||||
AC_CHECK_FUNCS([BN_GENCB_new ERR_remove_state RSA_set0_key], , , [#include <openssl/rsa.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
|
#! /bin/sh
|
||||||
# Common wrapper for a few potentially missing GNU programs.
|
# 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.
|
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
|
||||||
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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.
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
# You should have received a copy of the GNU General Public License
|
# 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
|
# As a special exception to the GNU General Public License, if you
|
||||||
# distribute this file as part of a program that contains a
|
# distribute this file as part of a program that contains a
|
||||||
|
@ -101,9 +101,9 @@ else
|
||||||
exit $st
|
exit $st
|
||||||
fi
|
fi
|
||||||
|
|
||||||
perl_URL=http://www.perl.org/
|
perl_URL=https://www.perl.org/
|
||||||
flex_URL=http://flex.sourceforge.net/
|
flex_URL=https://github.com/westes/flex
|
||||||
gnu_software_URL=http://www.gnu.org/software
|
gnu_software_URL=https://www.gnu.org/software
|
||||||
|
|
||||||
program_details ()
|
program_details ()
|
||||||
{
|
{
|
||||||
|
@ -207,9 +207,9 @@ give_advice "$1" | sed -e '1s/^/WARNING: /' \
|
||||||
exit $st
|
exit $st
|
||||||
|
|
||||||
# Local variables:
|
# Local variables:
|
||||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
# eval: (add-hook 'before-save-hook 'time-stamp)
|
||||||
# time-stamp-start: "scriptversion="
|
# time-stamp-start: "scriptversion="
|
||||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
# time-stamp-time-zone: "UTC"
|
# time-stamp-time-zone: "UTC0"
|
||||||
# time-stamp-end: "; # UTC"
|
# time-stamp-end: "; # UTC"
|
||||||
# End:
|
# End:
|
||||||
|
|
|
@ -42,6 +42,7 @@ chacha_poly1305_SOURCES = \
|
||||||
chacha-poly1305/poly1305.c chacha-poly1305/poly1305.h
|
chacha-poly1305/poly1305.c chacha-poly1305/poly1305.h
|
||||||
|
|
||||||
tincd_SOURCES = \
|
tincd_SOURCES = \
|
||||||
|
address_cache.c address_cache.h \
|
||||||
autoconnect.c autoconnect.h \
|
autoconnect.c autoconnect.h \
|
||||||
buffer.c buffer.h \
|
buffer.c buffer.h \
|
||||||
cipher.h \
|
cipher.h \
|
||||||
|
@ -278,10 +279,11 @@ endif
|
||||||
tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS)
|
tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS)
|
||||||
sptps_speed_LDADD = -lrt
|
sptps_speed_LDADD = -lrt
|
||||||
|
|
||||||
LIBS = @LIBS@ -lm
|
LIBS = @LIBS@ -lm $(CODE_COVERAGE_LIBS)
|
||||||
|
|
||||||
if TUNEMU
|
if TUNEMU
|
||||||
LIBS += -lpcap
|
LIBS += -lpcap
|
||||||
endif
|
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@
|
# @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
|
# This Makefile.in is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# 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_cflags_warn_all.m4 \
|
||||||
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
|
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
|
||||||
$(top_srcdir)/m4/ax_check_link_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/ax_require_defined.m4 \
|
||||||
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \
|
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \
|
||||||
$(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.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)
|
tinc_OBJECTS = $(am_tinc_OBJECTS)
|
||||||
am__DEPENDENCIES_1 =
|
am__DEPENDENCIES_1 =
|
||||||
tinc_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
|
tinc_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
|
||||||
am__tincd_SOURCES_DIST = autoconnect.c autoconnect.h buffer.c buffer.h \
|
am__tincd_SOURCES_DIST = address_cache.c address_cache.h autoconnect.c \
|
||||||
cipher.h conf.c conf.h connection.c connection.h control.c \
|
autoconnect.h buffer.c buffer.h cipher.h conf.c conf.h \
|
||||||
control.h control_common.h crypto.h device.h digest.h dropin.c \
|
connection.c connection.h control.c control.h control_common.h \
|
||||||
dropin.h dummy_device.c ecdh.h ecdsa.h ecdsagen.h edge.c \
|
crypto.h device.h digest.h dropin.c dropin.h dummy_device.c \
|
||||||
edge.h ethernet.h event.c event.h fd_device.c graph.c graph.h \
|
ecdh.h ecdsa.h ecdsagen.h edge.c edge.h ethernet.h event.c \
|
||||||
hash.c hash.h have.h ipv4.h ipv6.h list.c list.h logger.c \
|
event.h fd_device.c graph.c graph.h hash.c hash.h have.h \
|
||||||
logger.h meta.c meta.h multicast_device.c names.c names.h \
|
ipv4.h ipv6.h list.c list.h logger.c logger.h meta.c meta.h \
|
||||||
net.c net.h net_packet.c net_setup.c net_socket.c netutl.c \
|
multicast_device.c names.c names.h net.c net.h net_packet.c \
|
||||||
netutl.h node.c node.h prf.h process.c process.h protocol.c \
|
net_setup.c net_socket.c netutl.c netutl.h node.c node.h prf.h \
|
||||||
protocol.h protocol_auth.c protocol_edge.c protocol_key.c \
|
process.c process.h protocol.c protocol.h protocol_auth.c \
|
||||||
protocol_misc.c protocol_subnet.c raw_socket_device.c route.c \
|
protocol_edge.c protocol_key.c protocol_misc.c \
|
||||||
route.h rsa.h rsagen.h script.c script.h splay_tree.c \
|
protocol_subnet.c raw_socket_device.c route.c route.h rsa.h \
|
||||||
splay_tree.h sptps.c sptps.h subnet.c subnet.h subnet_parse.c \
|
rsagen.h script.c script.h splay_tree.c splay_tree.h sptps.c \
|
||||||
system.h tincd.c utils.c utils.h xalloc.h version.c version.h \
|
sptps.h subnet.c subnet.h subnet_parse.c system.h tincd.c \
|
||||||
ed25519/ecdh.c ed25519/ecdsa.c ed25519/ed25519.h ed25519/fe.c \
|
utils.c utils.h xalloc.h version.c version.h ed25519/ecdh.c \
|
||||||
ed25519/fe.h ed25519/fixedint.h ed25519/ge.c ed25519/ge.h \
|
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/key_exchange.c ed25519/keypair.c \
|
||||||
ed25519/precomp_data.h ed25519/sc.c ed25519/sc.h \
|
ed25519/precomp_data.h ed25519/sc.c ed25519/sc.h \
|
||||||
ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \
|
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/prf.$(OBJEXT) \
|
||||||
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/rsa.$(OBJEXT)
|
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/rsa.$(OBJEXT)
|
||||||
@MINIUPNPC_TRUE@am__objects_23 = upnp.$(OBJEXT)
|
@MINIUPNPC_TRUE@am__objects_23 = upnp.$(OBJEXT)
|
||||||
am_tincd_OBJECTS = autoconnect.$(OBJEXT) buffer.$(OBJEXT) \
|
am_tincd_OBJECTS = address_cache.$(OBJEXT) autoconnect.$(OBJEXT) \
|
||||||
conf.$(OBJEXT) connection.$(OBJEXT) control.$(OBJEXT) \
|
buffer.$(OBJEXT) conf.$(OBJEXT) connection.$(OBJEXT) \
|
||||||
dropin.$(OBJEXT) dummy_device.$(OBJEXT) edge.$(OBJEXT) \
|
control.$(OBJEXT) dropin.$(OBJEXT) dummy_device.$(OBJEXT) \
|
||||||
event.$(OBJEXT) fd_device.$(OBJEXT) graph.$(OBJEXT) \
|
edge.$(OBJEXT) event.$(OBJEXT) fd_device.$(OBJEXT) \
|
||||||
hash.$(OBJEXT) list.$(OBJEXT) logger.$(OBJEXT) meta.$(OBJEXT) \
|
graph.$(OBJEXT) hash.$(OBJEXT) list.$(OBJEXT) logger.$(OBJEXT) \
|
||||||
multicast_device.$(OBJEXT) names.$(OBJEXT) net.$(OBJEXT) \
|
meta.$(OBJEXT) multicast_device.$(OBJEXT) names.$(OBJEXT) \
|
||||||
net_packet.$(OBJEXT) net_setup.$(OBJEXT) net_socket.$(OBJEXT) \
|
net.$(OBJEXT) net_packet.$(OBJEXT) net_setup.$(OBJEXT) \
|
||||||
netutl.$(OBJEXT) node.$(OBJEXT) process.$(OBJEXT) \
|
net_socket.$(OBJEXT) netutl.$(OBJEXT) node.$(OBJEXT) \
|
||||||
protocol.$(OBJEXT) protocol_auth.$(OBJEXT) \
|
process.$(OBJEXT) protocol.$(OBJEXT) protocol_auth.$(OBJEXT) \
|
||||||
protocol_edge.$(OBJEXT) protocol_key.$(OBJEXT) \
|
protocol_edge.$(OBJEXT) protocol_key.$(OBJEXT) \
|
||||||
protocol_misc.$(OBJEXT) protocol_subnet.$(OBJEXT) \
|
protocol_misc.$(OBJEXT) protocol_subnet.$(OBJEXT) \
|
||||||
raw_socket_device.$(OBJEXT) route.$(OBJEXT) script.$(OBJEXT) \
|
raw_socket_device.$(OBJEXT) route.$(OBJEXT) script.$(OBJEXT) \
|
||||||
|
@ -423,7 +425,54 @@ am__v_at_0 = @
|
||||||
am__v_at_1 =
|
am__v_at_1 =
|
||||||
DEFAULT_INCLUDES =
|
DEFAULT_INCLUDES =
|
||||||
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
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
|
am__mv = mv -f
|
||||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||||
|
@ -478,6 +527,12 @@ AWK = @AWK@
|
||||||
CC = @CC@
|
CC = @CC@
|
||||||
CCDEPMODE = @CCDEPMODE@
|
CCDEPMODE = @CCDEPMODE@
|
||||||
CFLAGS = @CFLAGS@
|
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@
|
CPP = @CPP@
|
||||||
CPPFLAGS = @CPPFLAGS@
|
CPPFLAGS = @CPPFLAGS@
|
||||||
CURSES_LIBS = @CURSES_LIBS@
|
CURSES_LIBS = @CURSES_LIBS@
|
||||||
|
@ -489,16 +544,18 @@ ECHO_N = @ECHO_N@
|
||||||
ECHO_T = @ECHO_T@
|
ECHO_T = @ECHO_T@
|
||||||
EGREP = @EGREP@
|
EGREP = @EGREP@
|
||||||
EXEEXT = @EXEEXT@
|
EXEEXT = @EXEEXT@
|
||||||
|
GCOV = @GCOV@
|
||||||
|
GENHTML = @GENHTML@
|
||||||
GREP = @GREP@
|
GREP = @GREP@
|
||||||
INSTALL = @INSTALL@
|
INSTALL = @INSTALL@
|
||||||
INSTALL_DATA = @INSTALL_DATA@
|
INSTALL_DATA = @INSTALL_DATA@
|
||||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||||
|
LCOV = @LCOV@
|
||||||
LDFLAGS = @LDFLAGS@
|
LDFLAGS = @LDFLAGS@
|
||||||
LIBOBJS = @LIBOBJS@
|
LIBOBJS = @LIBOBJS@
|
||||||
LIBS = @LIBS@ -lm $(am__append_30)
|
LIBS = @LIBS@ -lm $(CODE_COVERAGE_LIBS) $(am__append_30)
|
||||||
LN_S = @LN_S@
|
|
||||||
LTLIBOBJS = @LTLIBOBJS@
|
LTLIBOBJS = @LTLIBOBJS@
|
||||||
MAKEINFO = @MAKEINFO@
|
MAKEINFO = @MAKEINFO@
|
||||||
MINIUPNPC_LIBS = @MINIUPNPC_LIBS@
|
MINIUPNPC_LIBS = @MINIUPNPC_LIBS@
|
||||||
|
@ -513,6 +570,7 @@ PACKAGE_URL = @PACKAGE_URL@
|
||||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||||
READLINE_LIBS = @READLINE_LIBS@
|
READLINE_LIBS = @READLINE_LIBS@
|
||||||
|
SED = @SED@
|
||||||
SET_MAKE = @SET_MAKE@
|
SET_MAKE = @SET_MAKE@
|
||||||
SHELL = @SHELL@
|
SHELL = @SHELL@
|
||||||
STRIP = @STRIP@
|
STRIP = @STRIP@
|
||||||
|
@ -588,16 +646,17 @@ chacha_poly1305_SOURCES = \
|
||||||
chacha-poly1305/chacha-poly1305.c chacha-poly1305/chacha-poly1305.h \
|
chacha-poly1305/chacha-poly1305.c chacha-poly1305/chacha-poly1305.h \
|
||||||
chacha-poly1305/poly1305.c chacha-poly1305/poly1305.h
|
chacha-poly1305/poly1305.c chacha-poly1305/poly1305.h
|
||||||
|
|
||||||
tincd_SOURCES = autoconnect.c autoconnect.h buffer.c buffer.h cipher.h \
|
tincd_SOURCES = address_cache.c address_cache.h autoconnect.c \
|
||||||
conf.c conf.h connection.c connection.h control.c control.h \
|
autoconnect.h buffer.c buffer.h cipher.h conf.c conf.h \
|
||||||
control_common.h crypto.h device.h digest.h dropin.c dropin.h \
|
connection.c connection.h control.c control.h control_common.h \
|
||||||
dummy_device.c ecdh.h ecdsa.h ecdsagen.h edge.c edge.h \
|
crypto.h device.h digest.h dropin.c dropin.h dummy_device.c \
|
||||||
ethernet.h event.c event.h fd_device.c graph.c graph.h hash.c \
|
ecdh.h ecdsa.h ecdsagen.h edge.c edge.h ethernet.h event.c \
|
||||||
hash.h have.h ipv4.h ipv6.h list.c list.h logger.c logger.h \
|
event.h fd_device.c graph.c graph.h hash.c hash.h have.h \
|
||||||
meta.c meta.h multicast_device.c names.c names.h net.c net.h \
|
ipv4.h ipv6.h list.c list.h logger.c logger.h meta.c meta.h \
|
||||||
net_packet.c net_setup.c net_socket.c netutl.c netutl.h node.c \
|
multicast_device.c names.c names.h net.c net.h net_packet.c \
|
||||||
node.h prf.h process.c process.h protocol.c protocol.h \
|
net_setup.c net_socket.c netutl.c netutl.h node.c node.h prf.h \
|
||||||
protocol_auth.c protocol_edge.c protocol_key.c protocol_misc.c \
|
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 \
|
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 \
|
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 \
|
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
|
@MINIUPNPC_TRUE@tincd_LDFLAGS = -pthread
|
||||||
tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS)
|
tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS)
|
||||||
sptps_speed_LDADD = -lrt
|
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
|
all: all-am
|
||||||
|
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
|
@ -654,8 +714,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||||
*config.status*) \
|
*config.status*) \
|
||||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||||
*) \
|
*) \
|
||||||
echo ' 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__depfiles_maybe);; \
|
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
|
||||||
esac;
|
esac;
|
||||||
|
|
||||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||||
|
@ -893,94 +953,101 @@ mostlyclean-compile:
|
||||||
distclean-compile:
|
distclean-compile:
|
||||||
-rm -f *.tab.c
|
-rm -f *.tab.c
|
||||||
|
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/autoconnect.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)/buffer.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/autoconnect.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conf.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buffer.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connection.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conf.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/control.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connection.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dropin.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/control.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy_device.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dropin.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edge.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy_device.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edge.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fd_device.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsck.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fd_device.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsck.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/graph.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/graph.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ifconfig.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/info.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ifconfig.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/invitation.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/info.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/invitation.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logger.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meta.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logger.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/multicast_device.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meta.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/names.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/multicast_device.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/names.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_packet.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_setup.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_packet.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_socket.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_setup.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netutl.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_socket.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/node.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netutl.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/node.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_auth.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_edge.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_auth.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_key.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_edge.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_misc.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_key.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_subnet.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_misc.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/raw_socket_device.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_subnet.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/route.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/raw_socket_device.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/script.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/route.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/splay_tree.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/script.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/splay_tree.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_keypair.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_speed.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_keypair.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_test.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_speed.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subnet.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_test.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subnet_parse.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subnet.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tincctl.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subnet_parse.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tincd.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tincctl.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/top.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tincd.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uml_device.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/top.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upnp.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uml_device.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upnp.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vde_device.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vde_device.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@bsd/$(DEPDIR)/device.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@bsd/$(DEPDIR)/tunemu.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@bsd/$(DEPDIR)/device.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/chacha-poly1305.Po@am__quote@
|
@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.Po@am__quote@
|
@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)/poly1305.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/chacha.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@cygwin/$(DEPDIR)/device.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/poly1305.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdh.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@cygwin/$(DEPDIR)/device.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdsa.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdh.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdsagen.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdsa.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/fe.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdsagen.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ge.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/fe.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/key_exchange.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ge.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/keypair.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/key_exchange.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/sc.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/keypair.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/sha512.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/sc.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/sign.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/sha512.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/verify.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/sign.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/cipher.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/verify.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/crypto.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/cipher.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/digest.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/crypto.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/prf.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/digest.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/rsa.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/prf.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/rsagen.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/rsa.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@linux/$(DEPDIR)/device.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/rsagen.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@mingw/$(DEPDIR)/device.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@linux/$(DEPDIR)/device.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@nolegacy/$(DEPDIR)/crypto.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@mingw/$(DEPDIR)/device.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@nolegacy/$(DEPDIR)/prf.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@nolegacy/$(DEPDIR)/crypto.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/cipher.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@nolegacy/$(DEPDIR)/prf.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/crypto.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/cipher.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/digest.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/crypto.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/prf.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/digest.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/rsa.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/prf.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/rsagen.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/rsa.Po@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@solaris/$(DEPDIR)/device.Po@am__quote@
|
@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:
|
.c.o:
|
||||||
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.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:
|
distclean-tags:
|
||||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH 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'`; \
|
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||||
list='$(DISTFILES)'; \
|
list='$(DISTFILES)'; \
|
||||||
|
@ -1145,7 +1215,95 @@ clean-am: clean-checkPROGRAMS clean-generic clean-sbinPROGRAMS \
|
||||||
mostlyclean-am
|
mostlyclean-am
|
||||||
|
|
||||||
distclean: distclean-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
|
-rm -f Makefile
|
||||||
distclean-am: clean-am distclean-compile distclean-generic \
|
distclean-am: clean-am distclean-compile distclean-generic \
|
||||||
distclean-tags
|
distclean-tags
|
||||||
|
@ -1191,7 +1349,95 @@ install-ps-am:
|
||||||
installcheck-am: installcheck-sbinPROGRAMS
|
installcheck-am: installcheck-sbinPROGRAMS
|
||||||
|
|
||||||
maintainer-clean: maintainer-clean-am
|
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
|
-rm -f Makefile
|
||||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||||
|
|
||||||
|
@ -1211,7 +1457,7 @@ uninstall-am: uninstall-sbinPROGRAMS
|
||||||
|
|
||||||
.MAKE: check-am install-am install-strip
|
.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 \
|
clean-checkPROGRAMS clean-generic clean-sbinPROGRAMS \
|
||||||
cscopelist-am ctags ctags-am distclean distclean-compile \
|
cscopelist-am ctags ctags-am distclean distclean-compile \
|
||||||
distclean-generic distclean-tags distdir dvi dvi-am html \
|
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() {
|
static void make_new_connection() {
|
||||||
/* Select a random node we haven't connected to yet. */
|
/* Select a random node we haven't connected to yet. */
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
for splay_each(node_t, n, node_tree) {
|
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;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!count)
|
if(!count) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int r = rand() % count;
|
int r = rand() % count;
|
||||||
|
|
||||||
for splay_each(node_t, n, node_tree) {
|
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;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if(r--)
|
if(r--) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
for list_each(outgoing_t, outgoing, outgoing_list) {
|
for list_each(outgoing_t, outgoing, outgoing_list) {
|
||||||
if(!strcmp(outgoing->name, n->name)) {
|
if(outgoing->node == n) {
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -56,10 +62,10 @@ static void make_new_connection() {
|
||||||
|
|
||||||
if(!found) {
|
if(!found) {
|
||||||
logger(DEBUG_CONNECTIONS, LOG_INFO, "Autoconnecting to %s", n->name);
|
logger(DEBUG_CONNECTIONS, LOG_INFO, "Autoconnecting to %s", n->name);
|
||||||
outgoing_t *outgoing = xzalloc(sizeof *outgoing);
|
outgoing_t *outgoing = xzalloc(sizeof(*outgoing));
|
||||||
outgoing->name = xstrdup(n->name);
|
outgoing->node = n;
|
||||||
list_insert_tail(outgoing_list, outgoing);
|
list_insert_tail(outgoing_list, outgoing);
|
||||||
setup_outgoing_connection(outgoing);
|
setup_outgoing_connection(outgoing, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -77,23 +83,27 @@ static void connect_to_unreachable() {
|
||||||
int r = rand() % node_tree->count;
|
int r = rand() % node_tree->count;
|
||||||
|
|
||||||
for splay_each(node_t, n, node_tree) {
|
for splay_each(node_t, n, node_tree) {
|
||||||
if(r--)
|
if(r--) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* Is it unreachable and do we know an address for it? If not, return. */
|
/* 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;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Are we already trying to make an outgoing connection to it? If not, return. */
|
/* Are we already trying to make an outgoing connection to it? If so, return. */
|
||||||
for list_each(outgoing_t, outgoing, outgoing_list)
|
for list_each(outgoing_t, outgoing, outgoing_list) {
|
||||||
if(!strcmp(outgoing->name, n->name))
|
if(outgoing->node == n) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
logger(DEBUG_CONNECTIONS, LOG_INFO, "Autoconnecting to %s", n->name);
|
logger(DEBUG_CONNECTIONS, LOG_INFO, "Autoconnecting to %s", n->name);
|
||||||
outgoing_t *outgoing = xzalloc(sizeof *outgoing);
|
outgoing_t *outgoing = xzalloc(sizeof(*outgoing));
|
||||||
outgoing->name = xstrdup(n->name);
|
outgoing->node = n;
|
||||||
list_insert_tail(outgoing_list, outgoing);
|
list_insert_tail(outgoing_list, outgoing);
|
||||||
setup_outgoing_connection(outgoing);
|
setup_outgoing_connection(outgoing, false);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -102,23 +112,29 @@ static void connect_to_unreachable() {
|
||||||
static void drop_superfluous_outgoing_connection() {
|
static void drop_superfluous_outgoing_connection() {
|
||||||
/* Choose a random outgoing connection to a node that has at least one other connection. */
|
/* Choose a random outgoing connection to a node that has at least one other connection. */
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
for list_each(connection_t, c, connection_list) {
|
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;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!count)
|
if(!count) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int r = rand() % count;
|
int r = rand() % count;
|
||||||
|
|
||||||
for list_each(connection_t, c, connection_list) {
|
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;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if(r--)
|
if(r--) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
logger(DEBUG_CONNECTIONS, LOG_INFO, "Autodisconnecting from %s", c->name);
|
logger(DEBUG_CONNECTIONS, LOG_INFO, "Autodisconnecting from %s", c->name);
|
||||||
list_delete(outgoing_list, c->outgoing);
|
list_delete(outgoing_list, c->outgoing);
|
||||||
|
@ -132,6 +148,7 @@ static void drop_superfluous_pending_connections() {
|
||||||
for list_each(outgoing_t, o, outgoing_list) {
|
for list_each(outgoing_t, o, outgoing_list) {
|
||||||
/* Only look for connections that are waiting to be retried later. */
|
/* Only look for connections that are waiting to be retried later. */
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
for list_each(connection_t, c, connection_list) {
|
for list_each(connection_t, c, connection_list) {
|
||||||
if(c->outgoing == o) {
|
if(c->outgoing == o) {
|
||||||
found = true;
|
found = true;
|
||||||
|
@ -139,10 +156,11 @@ static void drop_superfluous_pending_connections() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(found)
|
if(found) {
|
||||||
continue;
|
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);
|
list_delete_node(outgoing_list, node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,10 +168,12 @@ static void drop_superfluous_pending_connections() {
|
||||||
void do_autoconnect() {
|
void do_autoconnect() {
|
||||||
/* Count number of active connections. */
|
/* Count number of active connections. */
|
||||||
int nc = 0;
|
int nc = 0;
|
||||||
|
|
||||||
for list_each(connection_t, c, connection_list) {
|
for list_each(connection_t, c, connection_list) {
|
||||||
if(c->edge)
|
if(c->edge) {
|
||||||
nc++;
|
nc++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Less than 3 connections? Eagerly try to make a new one. */
|
/* Less than 3 connections? Eagerly try to make a new one. */
|
||||||
if(nc < 3) {
|
if(nc < 3) {
|
||||||
|
@ -162,8 +182,9 @@ void do_autoconnect() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* More than 3 connections? See if we can get rid of a superfluous one. */
|
/* More than 3 connections? See if we can get rid of a superfluous one. */
|
||||||
if(nc > 3)
|
if(nc > 3) {
|
||||||
drop_superfluous_outgoing_connection();
|
drop_superfluous_outgoing_connection();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Check if there are unreachable nodes that we should try to connect to. */
|
/* 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
|
autoconnect.h -- header for autoconnect.c
|
||||||
Copyright (C) 2017 Guus Sliepen <guus@tinc-vpn.org>
|
Copyright (C) 2017 Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
@ -17,9 +20,6 @@
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TINC_AUTOCONNECT_H__
|
|
||||||
#define __TINC_AUTOCONNECT_H__
|
|
||||||
|
|
||||||
extern void do_autoconnect(void);
|
extern void do_autoconnect(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
116
src/bsd/device.c
116
src/bsd/device.c
|
@ -56,7 +56,7 @@ typedef enum device_type {
|
||||||
int device_fd = -1;
|
int device_fd = -1;
|
||||||
char *device = NULL;
|
char *device = NULL;
|
||||||
char *iface = NULL;
|
char *iface = NULL;
|
||||||
static char *device_info = NULL;
|
static const char *device_info = "OS X utun device";
|
||||||
#if defined(ENABLE_TUNEMU)
|
#if defined(ENABLE_TUNEMU)
|
||||||
static device_type_t device_type = DEVICE_TYPE_TUNEMU;
|
static device_type_t device_type = DEVICE_TYPE_TUNEMU;
|
||||||
#elif defined(HAVE_OPENBSD) || defined(HAVE_FREEBSD) || defined(HAVE_DRAGONFLY)
|
#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
|
#ifdef HAVE_NET_IF_UTUN_H
|
||||||
static bool setup_utun(void) {
|
static bool setup_utun(void) {
|
||||||
device_fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
|
device_fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
|
||||||
|
|
||||||
if(device_fd == -1) {
|
if(device_fd == -1) {
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "Could not open PF_SYSTEM socket: %s\n", strerror(errno));
|
logger(DEBUG_ALWAYS, LOG_ERR, "Could not open PF_SYSTEM socket: %s\n", strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ctl_info info = {};
|
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) {
|
if(ioctl(device_fd, CTLIOCGINFO, &info) == -1) {
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "ioctl(CTLIOCGINFO) failed: %s", strerror(errno));
|
logger(DEBUG_ALWAYS, LOG_ERR, "ioctl(CTLIOCGINFO) failed: %s", strerror(errno));
|
||||||
|
@ -83,15 +85,18 @@ static bool setup_utun(void) {
|
||||||
|
|
||||||
int unit = -1;
|
int unit = -1;
|
||||||
char *p = strstr(device, "utun"), *e = NULL;
|
char *p = strstr(device, "utun"), *e = NULL;
|
||||||
|
|
||||||
if(p) {
|
if(p) {
|
||||||
unit = strtol(p + 4, &e, 10);
|
unit = strtol(p + 4, &e, 10);
|
||||||
if(!e)
|
|
||||||
|
if(!e) {
|
||||||
unit = -1;
|
unit = -1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct sockaddr_ctl sc = {
|
struct sockaddr_ctl sc = {
|
||||||
.sc_id = info.ctl_id,
|
.sc_id = info.ctl_id,
|
||||||
.sc_len = sizeof sc,
|
.sc_len = sizeof(sc),
|
||||||
.sc_family = AF_SYSTEM,
|
.sc_family = AF_SYSTEM,
|
||||||
.ss_sysaddr = AF_SYS_CONTROL,
|
.ss_sysaddr = AF_SYS_CONTROL,
|
||||||
.sc_unit = unit + 1,
|
.sc_unit = unit + 1,
|
||||||
|
@ -103,15 +108,14 @@ static bool setup_utun(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
char name[64] = "";
|
char name[64] = "";
|
||||||
socklen_t len = sizeof name;
|
socklen_t len = sizeof(name);
|
||||||
|
|
||||||
if(getsockopt(device_fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, name, &len)) {
|
if(getsockopt(device_fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, name, &len)) {
|
||||||
iface = xstrdup(device);
|
iface = xstrdup(device);
|
||||||
} else {
|
} else {
|
||||||
iface = xstrdup(name);
|
iface = xstrdup(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
device_info = "OS X utun device";
|
|
||||||
|
|
||||||
logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info);
|
logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -124,36 +128,44 @@ static bool setup_device(void) {
|
||||||
// Find out if it's supposed to be a tun or a tap device
|
// Find out if it's supposed to be a tun or a tap device
|
||||||
|
|
||||||
char *type;
|
char *type;
|
||||||
|
|
||||||
if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) {
|
if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) {
|
||||||
if(!strcasecmp(type, "tun"))
|
if(!strcasecmp(type, "tun"))
|
||||||
/* use default */;
|
/* use default */;
|
||||||
|
|
||||||
#ifdef ENABLE_TUNEMU
|
#ifdef ENABLE_TUNEMU
|
||||||
else if(!strcasecmp(type, "tunemu"))
|
else if(!strcasecmp(type, "tunemu")) {
|
||||||
device_type = DEVICE_TYPE_TUNEMU;
|
device_type = DEVICE_TYPE_TUNEMU;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_NET_IF_UTUN_H
|
#ifdef HAVE_NET_IF_UTUN_H
|
||||||
else if(!strcasecmp(type, "utun"))
|
else if(!strcasecmp(type, "utun")) {
|
||||||
device_type = DEVICE_TYPE_UTUN;
|
device_type = DEVICE_TYPE_UTUN;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
else if(!strcasecmp(type, "tunnohead"))
|
else if(!strcasecmp(type, "tunnohead")) {
|
||||||
device_type = DEVICE_TYPE_TUN;
|
device_type = DEVICE_TYPE_TUN;
|
||||||
else if(!strcasecmp(type, "tunifhead"))
|
} else if(!strcasecmp(type, "tunifhead")) {
|
||||||
device_type = DEVICE_TYPE_TUNIFHEAD;
|
device_type = DEVICE_TYPE_TUNIFHEAD;
|
||||||
else if(!strcasecmp(type, "tap"))
|
} else if(!strcasecmp(type, "tap")) {
|
||||||
device_type = DEVICE_TYPE_TAP;
|
device_type = DEVICE_TYPE_TAP;
|
||||||
else {
|
} else {
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "Unknown device type %s!", type);
|
logger(DEBUG_ALWAYS, LOG_ERR, "Unknown device type %s!", type);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#ifdef HAVE_NET_IF_UTUN_H
|
#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;
|
device_type = DEVICE_TYPE_UTUN;
|
||||||
else
|
} else
|
||||||
#endif
|
#endif
|
||||||
if((device && strstr(device, "tap")) || routing_mode != RMODE_ROUTER)
|
if((device && strstr(device, "tap")) || routing_mode != RMODE_ROUTER) {
|
||||||
device_type = DEVICE_TYPE_TAP;
|
device_type = DEVICE_TYPE_TAP;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(routing_mode == RMODE_SWITCH && device_type != DEVICE_TYPE_TAP) {
|
if(routing_mode == RMODE_SWITCH && device_type != DEVICE_TYPE_TAP) {
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "Only tap devices support switch mode!");
|
logger(DEBUG_ALWAYS, LOG_ERR, "Only tap devices support switch mode!");
|
||||||
|
@ -163,16 +175,18 @@ static bool setup_device(void) {
|
||||||
// Find out which device file to open
|
// Find out which device file to open
|
||||||
|
|
||||||
if(!device) {
|
if(!device) {
|
||||||
if(device_type == DEVICE_TYPE_TAP)
|
if(device_type == DEVICE_TYPE_TAP) {
|
||||||
device = xstrdup(DEFAULT_TAP_DEVICE);
|
device = xstrdup(DEFAULT_TAP_DEVICE);
|
||||||
else
|
} else {
|
||||||
device = xstrdup(DEFAULT_TUN_DEVICE);
|
device = xstrdup(DEFAULT_TUN_DEVICE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Open the device
|
// Open the device
|
||||||
|
|
||||||
switch(device_type) {
|
switch(device_type) {
|
||||||
#ifdef ENABLE_TUNEMU
|
#ifdef ENABLE_TUNEMU
|
||||||
|
|
||||||
case DEVICE_TYPE_TUNEMU: {
|
case DEVICE_TYPE_TUNEMU: {
|
||||||
char dynamic_name[256] = "";
|
char dynamic_name[256] = "";
|
||||||
device_fd = tunemu_open(dynamic_name);
|
device_fd = tunemu_open(dynamic_name);
|
||||||
|
@ -180,9 +194,11 @@ static bool setup_device(void) {
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_NET_IF_UTUN_H
|
#ifdef HAVE_NET_IF_UTUN_H
|
||||||
|
|
||||||
case DEVICE_TYPE_UTUN:
|
case DEVICE_TYPE_UTUN:
|
||||||
return setup_utun();
|
return setup_utun();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
device_fd = open(device, O_RDWR | O_NONBLOCK);
|
device_fd = open(device, O_RDWR | O_NONBLOCK);
|
||||||
}
|
}
|
||||||
|
@ -204,70 +220,84 @@ static bool setup_device(void) {
|
||||||
realname = fdevname(device_fd);
|
realname = fdevname(device_fd);
|
||||||
#elif defined(HAVE_DEVNAME)
|
#elif defined(HAVE_DEVNAME)
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
if(!fstat(device_fd, &buf))
|
|
||||||
|
if(!fstat(device_fd, &buf)) {
|
||||||
realname = devname(buf.st_rdev, S_IFCHR);
|
realname = devname(buf.st_rdev, S_IFCHR);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(!realname)
|
if(!realname) {
|
||||||
realname = device;
|
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);
|
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.");
|
logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: Interface does not match Device. $INTERFACE might be set incorrectly.");
|
||||||
|
}
|
||||||
|
|
||||||
// Configure the device as best as we can
|
// Configure the device as best as we can
|
||||||
|
|
||||||
switch(device_type) {
|
switch(device_type) {
|
||||||
default:
|
default:
|
||||||
device_type = DEVICE_TYPE_TUN;
|
device_type = DEVICE_TYPE_TUN;
|
||||||
|
|
||||||
case DEVICE_TYPE_TUN:
|
case DEVICE_TYPE_TUN:
|
||||||
#ifdef TUNSIFHEAD
|
#ifdef TUNSIFHEAD
|
||||||
{
|
{
|
||||||
const int zero = 0;
|
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));
|
logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST)
|
#if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST)
|
||||||
{
|
{
|
||||||
const int mode = IFF_BROADCAST | IFF_MULTICAST;
|
const int mode = IFF_BROADCAST | IFF_MULTICAST;
|
||||||
ioctl(device_fd, TUNSIFMODE, &mode, sizeof mode);
|
ioctl(device_fd, TUNSIFMODE, &mode, sizeof(mode));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
device_info = "Generic BSD tun device";
|
device_info = "Generic BSD tun device";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DEVICE_TYPE_TUNIFHEAD:
|
case DEVICE_TYPE_TUNIFHEAD:
|
||||||
#ifdef TUNSIFHEAD
|
#ifdef TUNSIFHEAD
|
||||||
{
|
{
|
||||||
const int one = 1;
|
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));
|
logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST)
|
#if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST)
|
||||||
{
|
{
|
||||||
const int mode = IFF_BROADCAST | IFF_MULTICAST;
|
const int mode = IFF_BROADCAST | IFF_MULTICAST;
|
||||||
ioctl(device_fd, TUNSIFMODE, &mode, sizeof mode);
|
ioctl(device_fd, TUNSIFMODE, &mode, sizeof(mode));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
device_info = "Generic BSD tun device";
|
device_info = "Generic BSD tun device";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DEVICE_TYPE_TAP:
|
case DEVICE_TYPE_TAP:
|
||||||
if(routing_mode == RMODE_ROUTER)
|
if(routing_mode == RMODE_ROUTER) {
|
||||||
overwrite_mac = true;
|
overwrite_mac = true;
|
||||||
|
}
|
||||||
|
|
||||||
device_info = "Generic BSD tap device";
|
device_info = "Generic BSD tap device";
|
||||||
#ifdef TAPGIFNAME
|
#ifdef TAPGIFNAME
|
||||||
{
|
{
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
|
|
||||||
if(ioctl(device_fd, TAPGIFNAME, (void *)&ifr) == 0) {
|
if(ioctl(device_fd, TAPGIFNAME, (void *)&ifr) == 0) {
|
||||||
if(iface)
|
|
||||||
free(iface);
|
free(iface);
|
||||||
iface = xstrdup(ifr.ifr_name);
|
iface = xstrdup(ifr.ifr_name);
|
||||||
}
|
}
|
||||||
|
@ -276,6 +306,7 @@ static bool setup_device(void) {
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
#ifdef ENABLE_TUNEMU
|
#ifdef ENABLE_TUNEMU
|
||||||
|
|
||||||
case DEVICE_TYPE_TUNEMU:
|
case DEVICE_TYPE_TUNEMU:
|
||||||
device_info = "BSD tunemu device";
|
device_info = "BSD tunemu device";
|
||||||
break;
|
break;
|
||||||
|
@ -283,8 +314,11 @@ static bool setup_device(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SIOCGIFADDR
|
#ifdef SIOCGIFADDR
|
||||||
if(overwrite_mac)
|
|
||||||
|
if(overwrite_mac) {
|
||||||
ioctl(device_fd, SIOCGIFADDR, mymac.x);
|
ioctl(device_fd, SIOCGIFADDR, mymac.x);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info);
|
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) {
|
static void close_device(void) {
|
||||||
switch(device_type) {
|
switch(device_type) {
|
||||||
#ifdef ENABLE_TUNEMU
|
#ifdef ENABLE_TUNEMU
|
||||||
|
|
||||||
case DEVICE_TYPE_TUNEMU:
|
case DEVICE_TYPE_TUNEMU:
|
||||||
tunemu_close(device_fd);
|
tunemu_close(device_fd);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
close(device_fd);
|
close(device_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
device_fd = -1;
|
device_fd = -1;
|
||||||
|
|
||||||
free(device); device = NULL;
|
free(device);
|
||||||
free(iface); iface = NULL;
|
device = NULL;
|
||||||
|
free(iface);
|
||||||
|
iface = NULL;
|
||||||
device_info = NULL;
|
device_info = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,9 +355,9 @@ static bool read_packet(vpn_packet_t *packet) {
|
||||||
case DEVICE_TYPE_TUN:
|
case DEVICE_TYPE_TUN:
|
||||||
#ifdef ENABLE_TUNEMU
|
#ifdef ENABLE_TUNEMU
|
||||||
case DEVICE_TYPE_TUNEMU:
|
case DEVICE_TYPE_TUNEMU:
|
||||||
if(device_type == DEVICE_TYPE_TUNEMU)
|
if(device_type == DEVICE_TYPE_TUNEMU) {
|
||||||
inlen = tunemu_read(device_fd, DATA(packet) + 14, MTU - 14);
|
inlen = tunemu_read(device_fd, DATA(packet) + 14, MTU - 14);
|
||||||
else
|
} else
|
||||||
#endif
|
#endif
|
||||||
inlen = read(device_fd, DATA(packet) + 14, MTU - 14);
|
inlen = read(device_fd, DATA(packet) + 14, MTU - 14);
|
||||||
|
|
||||||
|
@ -333,10 +372,12 @@ static bool read_packet(vpn_packet_t *packet) {
|
||||||
DATA(packet)[12] = 0x08;
|
DATA(packet)[12] = 0x08;
|
||||||
DATA(packet)[13] = 0x00;
|
DATA(packet)[13] = 0x00;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 6:
|
case 6:
|
||||||
DATA(packet)[12] = 0x86;
|
DATA(packet)[12] = 0x86;
|
||||||
DATA(packet)[13] = 0xDD;
|
DATA(packet)[13] = 0xDD;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
logger(DEBUG_TRAFFIC, LOG_ERR,
|
logger(DEBUG_TRAFFIC, LOG_ERR,
|
||||||
"Unknown IP version %d while reading packet from %s %s",
|
"Unknown IP version %d while reading packet from %s %s",
|
||||||
|
@ -410,6 +451,7 @@ static bool write_packet(vpn_packet_t *packet) {
|
||||||
device, strerror(errno));
|
device, strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DEVICE_TYPE_UTUN:
|
case DEVICE_TYPE_UTUN:
|
||||||
|
@ -421,9 +463,11 @@ static bool write_packet(vpn_packet_t *packet) {
|
||||||
case 0x0800:
|
case 0x0800:
|
||||||
type = htonl(AF_INET);
|
type = htonl(AF_INET);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x86DD:
|
case 0x86DD:
|
||||||
type = htonl(AF_INET6);
|
type = htonl(AF_INET6);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
logger(DEBUG_TRAFFIC, LOG_ERR,
|
logger(DEBUG_TRAFFIC, LOG_ERR,
|
||||||
"Unknown address family %x while writing packet to %s %s",
|
"Unknown address family %x while writing packet to %s %s",
|
||||||
|
@ -431,13 +475,14 @@ static bool write_packet(vpn_packet_t *packet) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(DATA(packet) + 10, &type, sizeof type);
|
memcpy(DATA(packet) + 10, &type, sizeof(type));
|
||||||
|
|
||||||
if(write(device_fd, DATA(packet) + 10, packet->len - 10) < 0) {
|
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,
|
logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -447,15 +492,18 @@ static bool write_packet(vpn_packet_t *packet) {
|
||||||
device, strerror(errno));
|
device, strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef ENABLE_TUNEMU
|
#ifdef ENABLE_TUNEMU
|
||||||
|
|
||||||
case DEVICE_TYPE_TUNEMU:
|
case DEVICE_TYPE_TUNEMU:
|
||||||
if(tunemu_write(device_fd, DATA(packet) + 14, packet->len - 14) < 0) {
|
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,
|
logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info,
|
||||||
device, strerror(errno));
|
device, strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
179
src/bsd/tunemu.c
179
src/bsd/tunemu.c
|
@ -49,24 +49,21 @@
|
||||||
#define PPPIOCCONNECT _IOW('t', 58, int)
|
#define PPPIOCCONNECT _IOW('t', 58, int)
|
||||||
#define PPPIOCGUNIT _IOR('t', 86, int)
|
#define PPPIOCGUNIT _IOR('t', 86, int)
|
||||||
|
|
||||||
struct sockaddr_ppp
|
struct sockaddr_ppp {
|
||||||
{
|
|
||||||
u_int8_t ppp_len;
|
u_int8_t ppp_len;
|
||||||
u_int8_t ppp_family;
|
u_int8_t ppp_family;
|
||||||
u_int16_t ppp_proto;
|
u_int16_t ppp_proto;
|
||||||
u_int32_t ppp_cookie;
|
u_int32_t ppp_cookie;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum NPmode
|
enum NPmode {
|
||||||
{
|
|
||||||
NPMODE_PASS,
|
NPMODE_PASS,
|
||||||
NPMODE_DROP,
|
NPMODE_DROP,
|
||||||
NPMODE_ERROR,
|
NPMODE_ERROR,
|
||||||
NPMODE_QUEUE
|
NPMODE_QUEUE
|
||||||
};
|
};
|
||||||
|
|
||||||
struct npioctl
|
struct npioctl {
|
||||||
{
|
|
||||||
int protocol;
|
int protocol;
|
||||||
enum NPmode mode;
|
enum NPmode mode;
|
||||||
};
|
};
|
||||||
|
@ -83,58 +80,55 @@ static pcap_t *pcap = NULL;
|
||||||
static int data_buffer_length = 0;
|
static int data_buffer_length = 0;
|
||||||
static char *data_buffer = NULL;
|
static char *data_buffer = NULL;
|
||||||
|
|
||||||
static void tun_error(char *format, ...)
|
static void tun_error(char *format, ...) {
|
||||||
{
|
|
||||||
va_list vl;
|
va_list vl;
|
||||||
va_start(vl, format);
|
va_start(vl, format);
|
||||||
vsnprintf(tunemu_error, sizeof tunemu_error, format, vl);
|
vsnprintf(tunemu_error, sizeof(tunemu_error), format, vl);
|
||||||
va_end(vl);
|
va_end(vl);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tun_noerror()
|
static void tun_noerror() {
|
||||||
{
|
|
||||||
*tunemu_error = 0;
|
*tunemu_error = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void closeall()
|
static void closeall() {
|
||||||
{
|
|
||||||
int fd = getdtablesize();
|
int fd = getdtablesize();
|
||||||
while (fd--)
|
|
||||||
|
while(fd--) {
|
||||||
close(fd);
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
open("/dev/null", O_RDWR, 0);
|
open("/dev/null", O_RDWR, 0);
|
||||||
dup(0);
|
dup(0);
|
||||||
dup(0);
|
dup(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ppp_load_kext()
|
static int ppp_load_kext() {
|
||||||
{
|
|
||||||
int pid = fork();
|
int pid = fork();
|
||||||
if (pid < 0)
|
|
||||||
{
|
if(pid < 0) {
|
||||||
tun_error("fork for ppp kext: %s", strerror(errno));
|
tun_error("fork for ppp kext: %s", strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pid == 0)
|
if(pid == 0) {
|
||||||
{
|
|
||||||
closeall();
|
closeall();
|
||||||
execle("/sbin/kextload", "kextload", PPP_KEXT_PATH, NULL, NULL);
|
execle("/sbin/kextload", "kextload", PPP_KEXT_PATH, NULL, NULL);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int status;
|
int status;
|
||||||
while (waitpid(pid, &status, 0) < 0)
|
|
||||||
{
|
while(waitpid(pid, &status, 0) < 0) {
|
||||||
if (errno == EINTR)
|
if(errno == EINTR) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
tun_error("waitpid for ppp kext: %s", strerror(errno));
|
tun_error("waitpid for ppp kext: %s", strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WEXITSTATUS(status) != 0)
|
if(WEXITSTATUS(status) != 0) {
|
||||||
{
|
|
||||||
tun_error("could not load ppp kext \"%s\"", PPP_KEXT_PATH);
|
tun_error("could not load ppp kext \"%s\"", PPP_KEXT_PATH);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -143,18 +137,18 @@ static int ppp_load_kext()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ppp_new_instance()
|
static int ppp_new_instance() {
|
||||||
{
|
|
||||||
// create ppp socket
|
// create ppp socket
|
||||||
int ppp_sockfd = socket(PF_PPP, SOCK_RAW, PPPPROTO_CTL);
|
int ppp_sockfd = socket(PF_PPP, SOCK_RAW, PPPPROTO_CTL);
|
||||||
if (ppp_sockfd < 0)
|
|
||||||
{
|
if(ppp_sockfd < 0) {
|
||||||
if (ppp_load_kext() < 0)
|
if(ppp_load_kext() < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
ppp_sockfd = socket(PF_PPP, SOCK_RAW, PPPPROTO_CTL);
|
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));
|
tun_error("creating ppp socket: %s", strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -166,8 +160,8 @@ static int ppp_new_instance()
|
||||||
pppaddr.ppp_family = AF_PPP;
|
pppaddr.ppp_family = AF_PPP;
|
||||||
pppaddr.ppp_proto = PPPPROTO_CTL;
|
pppaddr.ppp_proto = PPPPROTO_CTL;
|
||||||
pppaddr.ppp_cookie = 0;
|
pppaddr.ppp_cookie = 0;
|
||||||
if (connect(ppp_sockfd, (struct sockaddr *)&pppaddr, sizeof(struct sockaddr_ppp)) < 0)
|
|
||||||
{
|
if(connect(ppp_sockfd, (struct sockaddr *)&pppaddr, sizeof(struct sockaddr_ppp)) < 0) {
|
||||||
tun_error("connecting ppp socket: %s", strerror(errno));
|
tun_error("connecting ppp socket: %s", strerror(errno));
|
||||||
close(ppp_sockfd);
|
close(ppp_sockfd);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -177,15 +171,15 @@ static int ppp_new_instance()
|
||||||
return ppp_sockfd;
|
return ppp_sockfd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ppp_new_unit(int *unit_number)
|
static int ppp_new_unit(int *unit_number) {
|
||||||
{
|
|
||||||
int fd = ppp_new_instance();
|
int fd = ppp_new_instance();
|
||||||
if (fd < 0)
|
|
||||||
|
if(fd < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
// create ppp unit
|
// 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));
|
tun_error("creating ppp unit: %s", strerror(errno));
|
||||||
close(fd);
|
close(fd);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -195,12 +189,11 @@ static int ppp_new_unit(int *unit_number)
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ppp_setup_unit(int unit_fd)
|
static int ppp_setup_unit(int unit_fd) {
|
||||||
{
|
|
||||||
// send traffic to program
|
// send traffic to program
|
||||||
int flags = SC_LOOP_TRAFFIC;
|
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));
|
tun_error("setting ppp loopback mode: %s", strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -209,8 +202,8 @@ static int ppp_setup_unit(int unit_fd)
|
||||||
struct npioctl npi;
|
struct npioctl npi;
|
||||||
npi.protocol = PPP_IP;
|
npi.protocol = PPP_IP;
|
||||||
npi.mode = NPMODE_PASS;
|
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));
|
tun_error("starting ppp unit: %s", strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -219,10 +212,8 @@ static int ppp_setup_unit(int unit_fd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int open_pcap()
|
static int open_pcap() {
|
||||||
{
|
if(pcap != NULL) {
|
||||||
if (pcap != NULL)
|
|
||||||
{
|
|
||||||
pcap_use_count++;
|
pcap_use_count++;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -231,8 +222,7 @@ static int open_pcap()
|
||||||
pcap = pcap_open_live("lo0", BUFSIZ, 0, 1, errbuf);
|
pcap = pcap_open_live("lo0", BUFSIZ, 0, 1, errbuf);
|
||||||
pcap_use_count = 1;
|
pcap_use_count = 1;
|
||||||
|
|
||||||
if (pcap == NULL)
|
if(pcap == NULL) {
|
||||||
{
|
|
||||||
tun_error("opening pcap: %s", errbuf);
|
tun_error("opening pcap: %s", errbuf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -241,59 +231,57 @@ static int open_pcap()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void close_pcap()
|
static void close_pcap() {
|
||||||
{
|
if(pcap == NULL) {
|
||||||
if (pcap == NULL)
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
pcap_use_count--;
|
pcap_use_count--;
|
||||||
if (pcap_use_count == 0)
|
|
||||||
{
|
if(pcap_use_count == 0) {
|
||||||
pcap_close(pcap);
|
pcap_close(pcap);
|
||||||
pcap = NULL;
|
pcap = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void allocate_data_buffer(int size)
|
static void allocate_data_buffer(int size) {
|
||||||
{
|
if(data_buffer_length < size) {
|
||||||
if (data_buffer_length < size)
|
|
||||||
{
|
|
||||||
free(data_buffer);
|
free(data_buffer);
|
||||||
data_buffer_length = size;
|
data_buffer_length = size;
|
||||||
data_buffer = malloc(data_buffer_length);
|
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);
|
snprintf(device, sizeof(tunemu_device), "ppp%d", unit_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int check_device_name(tunemu_device device)
|
static int check_device_name(tunemu_device device) {
|
||||||
{
|
if(strlen(device) < 4) {
|
||||||
if (strlen(device) < 4)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int unit_number = atoi(device + 3);
|
int unit_number = atoi(device + 3);
|
||||||
if (unit_number < 0 || unit_number > 999)
|
|
||||||
|
if(unit_number < 0 || unit_number > 999) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
tunemu_device compare;
|
tunemu_device compare;
|
||||||
make_device_name(compare, unit_number);
|
make_device_name(compare, unit_number);
|
||||||
|
|
||||||
if (strcmp(device, compare) != 0)
|
if(strcmp(device, compare) != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tunemu_open(tunemu_device device)
|
int tunemu_open(tunemu_device device) {
|
||||||
{
|
|
||||||
int ppp_unit_number = -1;
|
int ppp_unit_number = -1;
|
||||||
if (device[0] != 0)
|
|
||||||
{
|
if(device[0] != 0) {
|
||||||
if (check_device_name(device) < 0)
|
if(check_device_name(device) < 0) {
|
||||||
{
|
|
||||||
tun_error("invalid device name \"%s\"", device);
|
tun_error("invalid device name \"%s\"", device);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -302,17 +290,17 @@ int tunemu_open(tunemu_device device)
|
||||||
}
|
}
|
||||||
|
|
||||||
int ppp_unit_fd = ppp_new_unit(&ppp_unit_number);
|
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);
|
close(ppp_unit_fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (open_pcap() < 0)
|
if(open_pcap() < 0) {
|
||||||
{
|
|
||||||
close(ppp_unit_fd);
|
close(ppp_unit_fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -322,39 +310,40 @@ int tunemu_open(tunemu_device device)
|
||||||
return ppp_unit_fd;
|
return ppp_unit_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tunemu_close(int ppp_sockfd)
|
int tunemu_close(int ppp_sockfd) {
|
||||||
{
|
|
||||||
int ret = close(ppp_sockfd);
|
int ret = close(ppp_sockfd);
|
||||||
|
|
||||||
if (ret == 0)
|
if(ret == 0) {
|
||||||
close_pcap();
|
close_pcap();
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
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);
|
allocate_data_buffer(length + 2);
|
||||||
|
|
||||||
length = read(ppp_sockfd, 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));
|
tun_error("reading packet: %s", strerror(errno));
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
tun_noerror();
|
tun_noerror();
|
||||||
|
|
||||||
length -= 2;
|
length -= 2;
|
||||||
if (length < 0)
|
|
||||||
|
if(length < 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(buffer, data_buffer + 2, length);
|
memcpy(buffer, data_buffer + 2, length);
|
||||||
|
|
||||||
return 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);
|
allocate_data_buffer(length + 4);
|
||||||
|
|
||||||
data_buffer[0] = 0x02;
|
data_buffer[0] = 0x02;
|
||||||
|
@ -364,23 +353,25 @@ int tunemu_write(int ppp_sockfd, char *buffer, int length)
|
||||||
|
|
||||||
memcpy(data_buffer + 4, buffer, length);
|
memcpy(data_buffer + 4, buffer, length);
|
||||||
|
|
||||||
if (pcap == NULL)
|
if(pcap == NULL) {
|
||||||
{
|
|
||||||
tun_error("pcap not open");
|
tun_error("pcap not open");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
length = pcap_inject(pcap, data_buffer, length + 4);
|
length = pcap_inject(pcap, data_buffer, length + 4);
|
||||||
if (length < 0)
|
|
||||||
{
|
if(length < 0) {
|
||||||
tun_error("injecting packet: %s", pcap_geterr(pcap));
|
tun_error("injecting packet: %s", pcap_geterr(pcap));
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
tun_noerror();
|
tun_noerror();
|
||||||
|
|
||||||
length -= 4;
|
length -= 4;
|
||||||
if (length < 0)
|
|
||||||
|
if(length < 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
18
src/buffer.c
18
src/buffer.c
|
@ -22,7 +22,7 @@
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "xalloc.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) {
|
if(buffer->len >= maxsize || buffer->offset / 7 > buffer->len / 8) {
|
||||||
memmove(buffer->data, buffer->data + buffer->offset, buffer->len - buffer->offset);
|
memmove(buffer->data, buffer->data + buffer->offset, buffer->len - 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.
|
// 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) {
|
if(!buffer->data) {
|
||||||
buffer->maxlen = size;
|
buffer->maxlen = size;
|
||||||
buffer->data = xmalloc(size);
|
buffer->data = xmalloc(size);
|
||||||
|
@ -58,13 +58,13 @@ char *buffer_prepare(buffer_t *buffer, int size) {
|
||||||
|
|
||||||
// Copy data into the buffer.
|
// 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);
|
memcpy(buffer_prepare(buffer, size), data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove given number of bytes from the buffer, return a pointer to the start of them.
|
// 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;
|
char *start = buffer->data + buffer->offset;
|
||||||
|
|
||||||
buffer->offset += size;
|
buffer->offset += size;
|
||||||
|
@ -82,19 +82,21 @@ static char *buffer_consume(buffer_t *buffer, int size) {
|
||||||
char *buffer_readline(buffer_t *buffer) {
|
char *buffer_readline(buffer_t *buffer) {
|
||||||
char *newline = memchr(buffer->data + buffer->offset, '\n', buffer->len - buffer->offset);
|
char *newline = memchr(buffer->data + buffer->offset, '\n', buffer->len - buffer->offset);
|
||||||
|
|
||||||
if(!newline)
|
if(!newline) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int len = newline + 1 - (buffer->data + buffer->offset);
|
uint32_t len = newline + 1 - (buffer->data + buffer->offset);
|
||||||
*newline = 0;
|
*newline = 0;
|
||||||
return buffer_consume(buffer, len);
|
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.
|
// 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) {
|
char *buffer_read(buffer_t *buffer, uint32_t size) {
|
||||||
if(buffer->len - buffer->offset < size)
|
if(buffer->len - buffer->offset < size) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return buffer_consume(buffer, size);
|
return buffer_consume(buffer, size);
|
||||||
}
|
}
|
||||||
|
|
18
src/buffer.h
18
src/buffer.h
|
@ -1,18 +1,18 @@
|
||||||
#ifndef __TINC_BUFFER_H__
|
#ifndef TINC_BUFFER_H
|
||||||
#define __TINC_BUFFER_H__
|
#define TINC_BUFFER_H
|
||||||
|
|
||||||
typedef struct buffer_t {
|
typedef struct buffer_t {
|
||||||
char *data;
|
char *data;
|
||||||
int maxlen;
|
uint32_t maxlen;
|
||||||
int len;
|
uint32_t len;
|
||||||
int offset;
|
uint32_t offset;
|
||||||
} buffer_t;
|
} buffer_t;
|
||||||
|
|
||||||
extern void buffer_compact(buffer_t *buffer, int maxsize);
|
extern void buffer_compact(buffer_t *buffer, uint32_t maxsize);
|
||||||
extern char *buffer_prepare(buffer_t *buffer, int size);
|
extern char *buffer_prepare(buffer_t *buffer, uint32_t size);
|
||||||
extern void buffer_add(buffer_t *buffer, const char *data, int size);
|
extern void buffer_add(buffer_t *buffer, const char *data, uint32_t size);
|
||||||
extern char *buffer_readline(buffer_t *buffer);
|
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);
|
extern void buffer_clear(buffer_t *buffer);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -11,26 +11,23 @@ struct chacha_poly1305_ctx {
|
||||||
struct chacha_ctx main_ctx, header_ctx;
|
struct chacha_ctx main_ctx, header_ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
chacha_poly1305_ctx_t *chacha_poly1305_init(void)
|
chacha_poly1305_ctx_t *chacha_poly1305_init(void) {
|
||||||
{
|
chacha_poly1305_ctx_t *ctx = xzalloc(sizeof(*ctx));
|
||||||
chacha_poly1305_ctx_t *ctx = xzalloc(sizeof *ctx);
|
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void chacha_poly1305_exit(chacha_poly1305_ctx_t *ctx)
|
void chacha_poly1305_exit(chacha_poly1305_ctx_t *ctx) {
|
||||||
{
|
|
||||||
free(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->main_ctx, key, 256);
|
||||||
chacha_keysetup(&ctx->header_ctx, key + 32, 256);
|
chacha_keysetup(&ctx->header_ctx, key + 32, 256);
|
||||||
return true;
|
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;
|
uint8_t *p = (uint8_t *) vp;
|
||||||
|
|
||||||
p[0] = (uint8_t)(v >> 56) & 0xff;
|
p[0] = (uint8_t)(v >> 56) & 0xff;
|
||||||
|
@ -43,10 +40,11 @@ static void put_u64(void *vp, uint64_t v)
|
||||||
p[7] = (uint8_t) v & 0xff;
|
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];
|
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 poly_key[POLY1305_KEYLEN];
|
||||||
|
uint8_t *outdata = voutdata;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Run ChaCha20 once to generate the Poly1305 key. The IV is the
|
* 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);
|
chacha_encrypt_bytes(&ctx->main_ctx, indata, outdata, inlen);
|
||||||
poly1305_auth(outdata + inlen, outdata, inlen, poly_key);
|
poly1305_auth(outdata + inlen, outdata, inlen, poly_key);
|
||||||
|
|
||||||
if (outlen)
|
if(outlen) {
|
||||||
*outlen = inlen + POLY1305_TAGLEN;
|
*outlen = inlen + POLY1305_TAGLEN;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
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];
|
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];
|
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
|
* 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;
|
const uint8_t *tag = indata + inlen;
|
||||||
|
|
||||||
poly1305_auth(expected_tag, indata, inlen, poly_key);
|
poly1305_auth(expected_tag, indata, inlen, poly_key);
|
||||||
if (memcmp(expected_tag, tag, POLY1305_TAGLEN))
|
|
||||||
|
if(memcmp(expected_tag, tag, POLY1305_TAGLEN)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
chacha_encrypt_bytes(&ctx->main_ctx, indata, outdata, inlen);
|
chacha_encrypt_bytes(&ctx->main_ctx, indata, outdata, inlen);
|
||||||
|
|
||||||
if (outlen)
|
if(outlen) {
|
||||||
*outlen = inlen;
|
*outlen = inlen;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,20 +47,21 @@ typedef struct chacha_ctx chacha_ctx;
|
||||||
static const char sigma[16] = "expand 32-byte k";
|
static const char sigma[16] = "expand 32-byte k";
|
||||||
static const char tau[16] = "expand 16-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;
|
const char *constants;
|
||||||
|
|
||||||
x->input[4] = U8TO32_LITTLE(k + 0);
|
x->input[4] = U8TO32_LITTLE(k + 0);
|
||||||
x->input[5] = U8TO32_LITTLE(k + 4);
|
x->input[5] = U8TO32_LITTLE(k + 4);
|
||||||
x->input[6] = U8TO32_LITTLE(k + 8);
|
x->input[6] = U8TO32_LITTLE(k + 8);
|
||||||
x->input[7] = U8TO32_LITTLE(k + 12);
|
x->input[7] = U8TO32_LITTLE(k + 12);
|
||||||
|
|
||||||
if(kbits == 256) { /* recommended */
|
if(kbits == 256) { /* recommended */
|
||||||
k += 16;
|
k += 16;
|
||||||
constants = sigma;
|
constants = sigma;
|
||||||
} else { /* kbits == 128 */
|
} else { /* kbits == 128 */
|
||||||
constants = tau;
|
constants = tau;
|
||||||
}
|
}
|
||||||
|
|
||||||
x->input[8] = U8TO32_LITTLE(k + 0);
|
x->input[8] = U8TO32_LITTLE(k + 0);
|
||||||
x->input[9] = U8TO32_LITTLE(k + 4);
|
x->input[9] = U8TO32_LITTLE(k + 4);
|
||||||
x->input[10] = U8TO32_LITTLE(k + 8);
|
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);
|
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[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0);
|
||||||
x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4);
|
x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4);
|
||||||
x->input[14] = U8TO32_LITTLE(iv + 0);
|
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
|
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 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;
|
uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
|
||||||
uint8_t *ctarget = NULL;
|
uint8_t *ctarget = NULL;
|
||||||
uint8_t tmp[64];
|
uint8_t tmp[64];
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
if (!bytes)
|
if(!bytes) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
j0 = x->input[0];
|
j0 = x->input[0];
|
||||||
j1 = x->input[1];
|
j1 = x->input[1];
|
||||||
|
@ -110,12 +110,15 @@ chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
if(bytes < 64) {
|
if(bytes < 64) {
|
||||||
for (i = 0; i < bytes; ++i)
|
for(i = 0; i < bytes; ++i) {
|
||||||
tmp[i] = m[i];
|
tmp[i] = m[i];
|
||||||
|
}
|
||||||
|
|
||||||
m = tmp;
|
m = tmp;
|
||||||
ctarget = c;
|
ctarget = c;
|
||||||
c = tmp;
|
c = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
x0 = j0;
|
x0 = j0;
|
||||||
x1 = j1;
|
x1 = j1;
|
||||||
x2 = j2;
|
x2 = j2;
|
||||||
|
@ -132,6 +135,7 @@ chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes
|
||||||
x13 = j13;
|
x13 = j13;
|
||||||
x14 = j14;
|
x14 = j14;
|
||||||
x15 = j15;
|
x15 = j15;
|
||||||
|
|
||||||
for(i = 20; i > 0; i -= 2) {
|
for(i = 20; i > 0; i -= 2) {
|
||||||
QUARTERROUND(x0, x4, x8, x12)
|
QUARTERROUND(x0, x4, x8, x12)
|
||||||
QUARTERROUND(x1, x5, x9, x13)
|
QUARTERROUND(x1, x5, x9, x13)
|
||||||
|
@ -142,6 +146,7 @@ chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes
|
||||||
QUARTERROUND(x2, x7, x8, x13)
|
QUARTERROUND(x2, x7, x8, x13)
|
||||||
QUARTERROUND(x3, x4, x9, x14)
|
QUARTERROUND(x3, x4, x9, x14)
|
||||||
}
|
}
|
||||||
|
|
||||||
x0 = PLUS(x0, j0);
|
x0 = PLUS(x0, j0);
|
||||||
x1 = PLUS(x1, j1);
|
x1 = PLUS(x1, j1);
|
||||||
x2 = PLUS(x2, j2);
|
x2 = PLUS(x2, j2);
|
||||||
|
@ -177,6 +182,7 @@ chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes
|
||||||
x15 = XOR(x15, U8TO32_LITTLE(m + 60));
|
x15 = XOR(x15, U8TO32_LITTLE(m + 60));
|
||||||
|
|
||||||
j12 = PLUSONE(j12);
|
j12 = PLUSONE(j12);
|
||||||
|
|
||||||
if(!j12) {
|
if(!j12) {
|
||||||
j13 = PLUSONE(j13);
|
j13 = PLUSONE(j13);
|
||||||
/* stopping at 2^70 bytes per nonce is user's responsibility */
|
/* stopping at 2^70 bytes per nonce is user's responsibility */
|
||||||
|
@ -201,13 +207,16 @@ chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes
|
||||||
|
|
||||||
if(bytes <= 64) {
|
if(bytes <= 64) {
|
||||||
if(bytes < 64) {
|
if(bytes < 64) {
|
||||||
for (i = 0; i < bytes; ++i)
|
for(i = 0; i < bytes; ++i) {
|
||||||
ctarget[i] = c[i];
|
ctarget[i] = c[i];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
x->input[12] = j12;
|
x->input[12] = j12;
|
||||||
x->input[13] = j13;
|
x->input[13] = j13;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes -= 64;
|
bytes -= 64;
|
||||||
c += 64;
|
c += 64;
|
||||||
m += 64;
|
m += 64;
|
||||||
|
|
|
@ -24,8 +24,7 @@
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
void
|
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 t0, t1, t2, t3;
|
||||||
uint32_t h0, h1, h2, h3, h4;
|
uint32_t h0, h1, h2, h3, h4;
|
||||||
uint32_t r0, r1, r2, r3, r4;
|
uint32_t r0, r1, r2, r3, r4;
|
||||||
|
@ -71,8 +70,9 @@ poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t
|
||||||
h4 = 0;
|
h4 = 0;
|
||||||
|
|
||||||
/* full blocks */
|
/* full blocks */
|
||||||
if (inlen < 16)
|
if(inlen < 16) {
|
||||||
goto poly1305_donna_atmost15bytes;
|
goto poly1305_donna_atmost15bytes;
|
||||||
|
}
|
||||||
|
|
||||||
poly1305_donna_16bytes:
|
poly1305_donna_16bytes:
|
||||||
m += 16;
|
m += 16;
|
||||||
|
@ -112,19 +112,27 @@ poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t
|
||||||
b = (uint32_t)(t[4] >> 26);
|
b = (uint32_t)(t[4] >> 26);
|
||||||
h0 += b * 5;
|
h0 += b * 5;
|
||||||
|
|
||||||
if (inlen >= 16)
|
if(inlen >= 16) {
|
||||||
goto poly1305_donna_16bytes;
|
goto poly1305_donna_16bytes;
|
||||||
|
}
|
||||||
|
|
||||||
/* final bytes */
|
/* final bytes */
|
||||||
poly1305_donna_atmost15bytes:
|
poly1305_donna_atmost15bytes:
|
||||||
if (!inlen)
|
|
||||||
goto poly1305_donna_finish;
|
|
||||||
|
|
||||||
for (j = 0; j < inlen; j++)
|
if(!inlen) {
|
||||||
|
goto poly1305_donna_finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(j = 0; j < inlen; j++) {
|
||||||
mp[j] = m[j];
|
mp[j] = m[j];
|
||||||
|
}
|
||||||
|
|
||||||
mp[j++] = 1;
|
mp[j++] = 1;
|
||||||
for (; j < 16; j++)
|
|
||||||
|
for(; j < 16; j++) {
|
||||||
mp[j] = 0;
|
mp[j] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
inlen = 0;
|
inlen = 0;
|
||||||
|
|
||||||
t0 = U8TO32_LE(mp + 0);
|
t0 = U8TO32_LE(mp + 0);
|
||||||
|
|
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
|
cipher.h -- header file cipher.c
|
||||||
Copyright (C) 2007-2016 Guus Sliepen <guus@tinc-vpn.org>
|
Copyright (C) 2007-2016 Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
@ -17,9 +20,6 @@
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
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_BLOCK_SIZE 32
|
||||||
#define CIPHER_MAX_IV_SIZE 16
|
#define CIPHER_MAX_IV_SIZE 16
|
||||||
#define CIPHER_MAX_KEY_SIZE 32
|
#define CIPHER_MAX_KEY_SIZE 32
|
||||||
|
@ -28,19 +28,18 @@
|
||||||
|
|
||||||
typedef struct cipher cipher_t;
|
typedef struct cipher cipher_t;
|
||||||
|
|
||||||
extern cipher_t *cipher_open_by_name(const char *) __attribute__ ((__malloc__));
|
extern cipher_t *cipher_open_by_name(const char *name) __attribute__((__malloc__));
|
||||||
extern cipher_t *cipher_open_by_nid(int) __attribute__ ((__malloc__));
|
extern cipher_t *cipher_open_by_nid(int nid) __attribute__((__malloc__));
|
||||||
extern void cipher_close(cipher_t *);
|
extern void cipher_close(cipher_t *cipher);
|
||||||
extern size_t cipher_keylength(const cipher_t *);
|
extern size_t cipher_keylength(const cipher_t *cipher);
|
||||||
extern size_t cipher_blocksize(const cipher_t *);
|
extern size_t cipher_blocksize(const cipher_t *cipher);
|
||||||
extern uint64_t cipher_budget(const cipher_t *);
|
extern uint64_t cipher_budget(const cipher_t *cipher);
|
||||||
extern void cipher_get_key(const cipher_t *, void *);
|
extern bool cipher_set_key(cipher_t *cipher, void *key, bool encrypt) __attribute__((__warn_unused_result__));
|
||||||
extern bool cipher_set_key(cipher_t *, void *, bool) __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_set_key_from_rsa(cipher_t *, void *, size_t, bool) __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_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 *cipher, 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 *cipher);
|
||||||
extern int cipher_get_nid(const cipher_t *);
|
extern bool cipher_active(const cipher_t *cipher);
|
||||||
extern bool cipher_active(const cipher_t *);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
142
src/conf.c
142
src/conf.c
|
@ -46,21 +46,25 @@ static int config_compare(const config_t *a, const config_t *b) {
|
||||||
|
|
||||||
result = strcasecmp(a->variable, b->variable);
|
result = strcasecmp(a->variable, b->variable);
|
||||||
|
|
||||||
if(result)
|
if(result) {
|
||||||
return result;
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/* give priority to command line options */
|
/* give priority to command line options */
|
||||||
result = !b->file - !a->file;
|
result = !b->file - !a->file;
|
||||||
if (result)
|
|
||||||
|
if(result) {
|
||||||
return result;
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
result = a->line - b->line;
|
result = a->line - b->line;
|
||||||
|
|
||||||
if(result)
|
if(result) {
|
||||||
return result;
|
return result;
|
||||||
else
|
} else {
|
||||||
return a->file ? strcmp(a->file, b->file) : 0;
|
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);
|
*config_tree = splay_alloc_tree((splay_compare_t) config_compare, (splay_action_t) free_config);
|
||||||
|
@ -76,15 +80,9 @@ config_t *new_config(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_config(config_t *cfg) {
|
void free_config(config_t *cfg) {
|
||||||
if(cfg->variable)
|
|
||||||
free(cfg->variable);
|
free(cfg->variable);
|
||||||
|
|
||||||
if(cfg->value)
|
|
||||||
free(cfg->value);
|
free(cfg->value);
|
||||||
|
|
||||||
if(cfg->file)
|
|
||||||
free(cfg->file);
|
free(cfg->file);
|
||||||
|
|
||||||
free(cfg);
|
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);
|
found = splay_search_closest_greater(config_tree, &cfg);
|
||||||
|
|
||||||
if(!found)
|
if(!found) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if(strcasecmp(found->variable, variable))
|
if(strcasecmp(found->variable, variable)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
@ -120,17 +120,19 @@ config_t *lookup_config_next(splay_tree_t *config_tree, const config_t *cfg) {
|
||||||
if(node->next) {
|
if(node->next) {
|
||||||
found = node->next->data;
|
found = node->next->data;
|
||||||
|
|
||||||
if(!strcasecmp(found->variable, cfg->variable))
|
if(!strcasecmp(found->variable, cfg->variable)) {
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get_config_bool(const config_t *cfg, bool *result) {
|
bool get_config_bool(const config_t *cfg, bool *result) {
|
||||||
if(!cfg)
|
if(!cfg) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if(!strcasecmp(cfg->value, "yes")) {
|
if(!strcasecmp(cfg->value, "yes")) {
|
||||||
*result = true;
|
*result = true;
|
||||||
|
@ -147,11 +149,13 @@ bool get_config_bool(const config_t *cfg, bool *result) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get_config_int(const config_t *cfg, int *result) {
|
bool get_config_int(const config_t *cfg, int *result) {
|
||||||
if(!cfg)
|
if(!cfg) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if(sscanf(cfg->value, "%d", result) == 1)
|
if(sscanf(cfg->value, "%d", result) == 1) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "Integer expected for configuration variable %s in %s line %d",
|
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);
|
||||||
|
@ -160,8 +164,9 @@ bool get_config_int(const config_t *cfg, int *result) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get_config_string(const config_t *cfg, char **result) {
|
bool get_config_string(const config_t *cfg, char **result) {
|
||||||
if(!cfg)
|
if(!cfg) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
*result = xstrdup(cfg->value);
|
*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) {
|
bool get_config_address(const config_t *cfg, struct addrinfo **result) {
|
||||||
struct addrinfo *ai;
|
struct addrinfo *ai;
|
||||||
|
|
||||||
if(!cfg)
|
if(!cfg) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ai = str2addrinfo(cfg->value, NULL, 0);
|
ai = str2addrinfo(cfg->value, NULL, 0);
|
||||||
|
|
||||||
|
@ -188,10 +194,11 @@ bool get_config_address(const config_t *cfg, struct addrinfo **result) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get_config_subnet(const config_t *cfg, subnet_t **result) {
|
bool get_config_subnet(const config_t *cfg, subnet_t **result) {
|
||||||
subnet_t subnet = {NULL};
|
subnet_t subnet = {0};
|
||||||
|
|
||||||
if(!cfg)
|
if(!cfg) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if(!str2net(&subnet, cfg->value)) {
|
if(!str2net(&subnet, cfg->value)) {
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "Subnet expected for configuration variable %s in %s line %d",
|
logger(DEBUG_ALWAYS, LOG_ERR, "Subnet expected for configuration variable %s in %s line %d",
|
||||||
|
@ -202,9 +209,9 @@ bool get_config_subnet(const config_t *cfg, subnet_t ** result) {
|
||||||
/* Teach newbies what subnets are... */
|
/* Teach newbies what subnets are... */
|
||||||
|
|
||||||
if(((subnet.type == SUBNET_IPV4)
|
if(((subnet.type == SUBNET_IPV4)
|
||||||
&& !maskcheck(&subnet.net.ipv4.address, subnet.net.ipv4.prefixlength, sizeof subnet.net.ipv4.address))
|
&& !maskcheck(&subnet.net.ipv4.address, subnet.net.ipv4.prefixlength, sizeof(subnet.net.ipv4.address)))
|
||||||
|| ((subnet.type == SUBNET_IPV6)
|
|| ((subnet.type == SUBNET_IPV6)
|
||||||
&& !maskcheck(&subnet.net.ipv6.address, subnet.net.ipv6.prefixlength, sizeof subnet.net.ipv6.address))) {
|
&& !maskcheck(&subnet.net.ipv6.address, subnet.net.ipv6.prefixlength, sizeof(subnet.net.ipv6.address)))) {
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "Network address and prefix length do not match for configuration variable %s in %s line %d",
|
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;
|
return false;
|
||||||
|
@ -222,23 +229,28 @@ static char *readline(FILE * fp, char *buf, size_t buflen) {
|
||||||
char *newline = NULL;
|
char *newline = NULL;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
if(feof(fp))
|
if(feof(fp)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
p = fgets(buf, buflen, fp);
|
p = fgets(buf, buflen, fp);
|
||||||
|
|
||||||
if(!p)
|
if(!p) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
newline = strchr(p, '\n');
|
newline = strchr(p, '\n');
|
||||||
|
|
||||||
if(!newline)
|
if(!newline) {
|
||||||
return buf;
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
/* kill newline and carriage return if necessary */
|
/* kill newline and carriage return if necessary */
|
||||||
*newline = '\0';
|
*newline = '\0';
|
||||||
if(newline > p && newline[-1] == '\r')
|
|
||||||
|
if(newline > p && newline[-1] == '\r') {
|
||||||
newline[-1] = '\0';
|
newline[-1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
@ -250,26 +262,32 @@ config_t *parse_config_line(char *line, const char *fname, int lineno) {
|
||||||
variable = value = line;
|
variable = value = line;
|
||||||
|
|
||||||
eol = line + strlen(line);
|
eol = line + strlen(line);
|
||||||
while(strchr("\t ", *--eol))
|
|
||||||
|
while(strchr("\t ", *--eol)) {
|
||||||
*eol = '\0';
|
*eol = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
len = strcspn(value, "\t =");
|
len = strcspn(value, "\t =");
|
||||||
value += len;
|
value += len;
|
||||||
value += strspn(value, "\t ");
|
value += strspn(value, "\t ");
|
||||||
|
|
||||||
if(*value == '=') {
|
if(*value == '=') {
|
||||||
value++;
|
value++;
|
||||||
value += strspn(value, "\t ");
|
value += strspn(value, "\t ");
|
||||||
}
|
}
|
||||||
|
|
||||||
variable[len] = '\0';
|
variable[len] = '\0';
|
||||||
|
|
||||||
if(!*value) {
|
if(!*value) {
|
||||||
const char err[] = "No value for variable";
|
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",
|
logger(DEBUG_ALWAYS, LOG_ERR, "%s `%s' on line %d while reading config file %s",
|
||||||
err, variable, lineno, fname);
|
err, variable, lineno, fname);
|
||||||
else
|
else
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "%s `%s' in command line option %d",
|
logger(DEBUG_ALWAYS, LOG_ERR, "%s `%s' in command line option %d",
|
||||||
err, variable, lineno);
|
err, variable, lineno);
|
||||||
|
|
||||||
return NULL;
|
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
|
Parse a configuration file and put the results in the configuration tree
|
||||||
starting at *base.
|
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;
|
FILE *fp;
|
||||||
char buffer[MAX_STRING_SIZE];
|
char buffer[MAX_STRING_SIZE];
|
||||||
char *line;
|
char *line;
|
||||||
|
@ -298,27 +316,32 @@ bool read_config_file(splay_tree_t *config_tree, const char *fname) {
|
||||||
fp = fopen(fname, "r");
|
fp = fopen(fname, "r");
|
||||||
|
|
||||||
if(!fp) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
line = readline(fp, buffer, sizeof buffer);
|
line = readline(fp, buffer, sizeof(buffer));
|
||||||
|
|
||||||
if(!line) {
|
if(!line) {
|
||||||
if(feof(fp))
|
if(feof(fp)) {
|
||||||
result = true;
|
result = true;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
lineno++;
|
lineno++;
|
||||||
|
|
||||||
if(!*line || *line == '#')
|
if(!*line || *line == '#') {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if(ignore) {
|
if(ignore) {
|
||||||
if(!strncmp(line, "-----END", 8))
|
if(!strncmp(line, "-----END", 8)) {
|
||||||
ignore = false;
|
ignore = false;
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,8 +351,11 @@ bool read_config_file(splay_tree_t *config_tree, const char *fname) {
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg = parse_config_line(line, fname, lineno);
|
cfg = parse_config_line(line, fname, lineno);
|
||||||
if (!cfg)
|
|
||||||
|
if(!cfg) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
config_add(config_tree, cfg);
|
config_add(config_tree, cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,19 +372,24 @@ void read_config_options(splay_tree_t *config_tree, const char *prefix) {
|
||||||
config_t *new;
|
config_t *new;
|
||||||
|
|
||||||
if(!prefix) {
|
if(!prefix) {
|
||||||
if(strchr(cfg->variable, '.'))
|
if(strchr(cfg->variable, '.')) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if(strncmp(prefix, cfg->variable, prefix_len) ||
|
if(strncmp(prefix, cfg->variable, prefix_len) ||
|
||||||
cfg->variable[prefix_len] != '.')
|
cfg->variable[prefix_len] != '.') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
new = new_config();
|
new = new_config();
|
||||||
if(prefix)
|
|
||||||
|
if(prefix) {
|
||||||
new->variable = xstrdup(cfg->variable + prefix_len + 1);
|
new->variable = xstrdup(cfg->variable + prefix_len + 1);
|
||||||
else
|
} else {
|
||||||
new->variable = xstrdup(cfg->variable);
|
new->variable = xstrdup(cfg->variable);
|
||||||
|
}
|
||||||
|
|
||||||
new->value = xstrdup(cfg->value);
|
new->value = xstrdup(cfg->value);
|
||||||
new->file = NULL;
|
new->file = NULL;
|
||||||
new->line = cfg->line;
|
new->line = cfg->line;
|
||||||
|
@ -373,52 +404,57 @@ bool read_server_config(void) {
|
||||||
|
|
||||||
read_config_options(config_tree, NULL);
|
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;
|
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
|
// We will try to read the conf files in the "conf.d" dir
|
||||||
if(x) {
|
if(x) {
|
||||||
char dname[PATH_MAX];
|
char dname[PATH_MAX];
|
||||||
snprintf(dname, sizeof dname, "%s" SLASH "conf.d", confbase);
|
snprintf(dname, sizeof(dname), "%s" SLASH "conf.d", confbase);
|
||||||
DIR *dir = opendir(dname);
|
DIR *dir = opendir(dname);
|
||||||
|
|
||||||
// If we can find this dir
|
// If we can find this dir
|
||||||
if(dir) {
|
if(dir) {
|
||||||
struct dirent *ep;
|
struct dirent *ep;
|
||||||
|
|
||||||
// We list all the files in it
|
// We list all the files in it
|
||||||
while(x && (ep = readdir(dir))) {
|
while(x && (ep = readdir(dir))) {
|
||||||
size_t l = strlen(ep->d_name);
|
size_t l = strlen(ep->d_name);
|
||||||
|
|
||||||
// And we try to read the ones that end with ".conf"
|
// And we try to read the ones that end with ".conf"
|
||||||
if(l > 5 && !strcmp(".conf", & ep->d_name[ l - 5 ])) {
|
if(l > 5 && !strcmp(".conf", & ep->d_name[ l - 5 ])) {
|
||||||
snprintf(fname, sizeof fname, "%s" SLASH "%s", dname, ep->d_name);
|
if((size_t)snprintf(fname, sizeof(fname), "%s" SLASH "%s", dname, ep->d_name) >= sizeof(fname)) {
|
||||||
x = read_config_file(config_tree, 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));
|
logger(DEBUG_ALWAYS, LOG_ERR, "Failed to read `%s': %s", fname, strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool read_host_config(splay_tree_t *config_tree, const char *name) {
|
bool read_host_config(splay_tree_t *config_tree, const char *name, bool verbose) {
|
||||||
char fname[PATH_MAX];
|
|
||||||
bool x;
|
|
||||||
|
|
||||||
read_config_options(config_tree, name);
|
read_config_options(config_tree, name);
|
||||||
|
|
||||||
snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, name);
|
char fname[PATH_MAX];
|
||||||
x = read_config_file(config_tree, fname);
|
snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, name);
|
||||||
|
return read_config_file(config_tree, fname, verbose);
|
||||||
return x;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool append_config_file(const char *name, const char *key, const char *value) {
|
bool append_config_file(const char *name, const char *key, const char *value) {
|
||||||
char fname[PATH_MAX];
|
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");
|
FILE *fp = fopen(fname, "a");
|
||||||
|
|
||||||
|
|
40
src/conf.h
40
src/conf.h
|
@ -1,3 +1,6 @@
|
||||||
|
#ifndef TINC_CONF_H
|
||||||
|
#define TINC_CONF_H
|
||||||
|
|
||||||
/*
|
/*
|
||||||
conf.h -- header for conf.c
|
conf.h -- header for conf.c
|
||||||
Copyright (C) 1998-2005 Ivo Timmermans
|
Copyright (C) 1998-2005 Ivo Timmermans
|
||||||
|
@ -18,9 +21,6 @@
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TINC_CONF_H__
|
|
||||||
#define __TINC_CONF_H__
|
|
||||||
|
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "splay_tree.h"
|
#include "splay_tree.h"
|
||||||
#include "subnet.h"
|
#include "subnet.h"
|
||||||
|
@ -41,24 +41,24 @@ extern int maxtimeout;
|
||||||
extern bool bypass_security;
|
extern bool bypass_security;
|
||||||
extern list_t *cmdline_conf;
|
extern list_t *cmdline_conf;
|
||||||
|
|
||||||
extern void init_configuration(splay_tree_t **);
|
extern void init_configuration(splay_tree_t **config_tree);
|
||||||
extern void exit_configuration(splay_tree_t **);
|
extern void exit_configuration(splay_tree_t **config_tree);
|
||||||
extern config_t *new_config(void) __attribute__((__malloc__));
|
extern config_t *new_config(void) __attribute__((__malloc__));
|
||||||
extern void free_config(config_t *);
|
extern void free_config(config_t *config);
|
||||||
extern void config_add(splay_tree_t *, config_t *);
|
extern void config_add(splay_tree_t *config_tree, config_t *config);
|
||||||
extern config_t *lookup_config(splay_tree_t *, char *);
|
extern config_t *lookup_config(splay_tree_t *config_tree, char *variable);
|
||||||
extern config_t *lookup_config_next(splay_tree_t *, const config_t *);
|
extern config_t *lookup_config_next(splay_tree_t *config_tree, const config_t *config);
|
||||||
extern bool get_config_bool(const config_t *, bool *);
|
extern bool get_config_bool(const config_t *config, bool *result);
|
||||||
extern bool get_config_int(const config_t *, int *);
|
extern bool get_config_int(const config_t *config, int *result);
|
||||||
extern bool get_config_string(const config_t *, char **);
|
extern bool get_config_string(const config_t *config, char **result);
|
||||||
extern bool get_config_address(const config_t *, struct addrinfo **);
|
extern bool get_config_address(const config_t *config, struct addrinfo **result);
|
||||||
extern bool get_config_subnet(const config_t *, struct subnet_t **);
|
extern bool get_config_subnet(const config_t *config, struct subnet_t **result);
|
||||||
|
|
||||||
extern config_t *parse_config_line(char *, const char *, int);
|
extern config_t *parse_config_line(char *line, const char *fname, int lineno);
|
||||||
extern bool read_config_file(splay_tree_t *, const char *);
|
extern bool read_config_file(splay_tree_t *config_tree, const char *filename, bool verbose);
|
||||||
extern void read_config_options(splay_tree_t *, const char *);
|
extern void read_config_options(splay_tree_t *config_tree, const char *prefix);
|
||||||
extern bool read_server_config(void);
|
extern bool read_server_config(void);
|
||||||
extern bool read_host_config(splay_tree_t *, const char *);
|
extern bool read_host_config(splay_tree_t *config_tree, const char *name, bool verbose);
|
||||||
extern bool append_config_file(const char *, const char *, const char *);
|
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 "control_common.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
|
#include "net.h"
|
||||||
#include "rsa.h"
|
#include "rsa.h"
|
||||||
#include "subnet.h"
|
#include "subnet.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
@ -52,8 +53,9 @@ connection_t *new_connection(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_connection(connection_t *c) {
|
void free_connection(connection_t *c) {
|
||||||
if(!c)
|
if(!c) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef DISABLE_LEGACY
|
#ifndef DISABLE_LEGACY
|
||||||
cipher_close(c->incipher);
|
cipher_close(c->incipher);
|
||||||
|
@ -67,20 +69,27 @@ void free_connection(connection_t *c) {
|
||||||
ecdsa_free(c->ecdsa);
|
ecdsa_free(c->ecdsa);
|
||||||
|
|
||||||
free(c->hischallenge);
|
free(c->hischallenge);
|
||||||
|
free(c->mychallenge);
|
||||||
|
|
||||||
buffer_clear(&c->inbuf);
|
buffer_clear(&c->inbuf);
|
||||||
buffer_clear(&c->outbuf);
|
buffer_clear(&c->outbuf);
|
||||||
|
|
||||||
io_del(&c->io);
|
io_del(&c->io);
|
||||||
|
|
||||||
if(c->socket > 0)
|
if(c->socket > 0) {
|
||||||
|
if(c->status.tarpit) {
|
||||||
|
tarpit(c->socket);
|
||||||
|
} else {
|
||||||
closesocket(c->socket);
|
closesocket(c->socket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
free(c->name);
|
free(c->name);
|
||||||
free(c->hostname);
|
free(c->hostname);
|
||||||
|
|
||||||
if(c->config_tree)
|
if(c->config_tree) {
|
||||||
exit_configuration(&c->config_tree);
|
exit_configuration(&c->config_tree);
|
||||||
|
}
|
||||||
|
|
||||||
free(c);
|
free(c);
|
||||||
}
|
}
|
||||||
|
@ -98,7 +107,7 @@ bool dump_connections(connection_t *cdump) {
|
||||||
send_request(cdump, "%d %d %s %s %x %d %x",
|
send_request(cdump, "%d %d %s %s %x %d %x",
|
||||||
CONTROL, REQ_DUMP_CONNECTIONS,
|
CONTROL, REQ_DUMP_CONNECTIONS,
|
||||||
c->name, c->hostname, c->options, c->socket,
|
c->name, c->hostname, c->options, c->socket,
|
||||||
bitfield_to_int(&c->status, sizeof c->status));
|
bitfield_to_int(&c->status, sizeof(c->status)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return send_request(cdump, "%d %d", CONTROL, REQ_DUMP_CONNECTIONS);
|
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
|
connection.h -- header for connection.c
|
||||||
Copyright (C) 2000-2013 Guus Sliepen <guus@tinc-vpn.org>,
|
Copyright (C) 2000-2013 Guus Sliepen <guus@tinc-vpn.org>,
|
||||||
|
@ -18,9 +21,6 @@
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TINC_CONNECTION_H__
|
|
||||||
#define __TINC_CONNECTION_H__
|
|
||||||
|
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "cipher.h"
|
#include "cipher.h"
|
||||||
#include "digest.h"
|
#include "digest.h"
|
||||||
|
@ -49,7 +49,8 @@ typedef struct connection_status_t {
|
||||||
unsigned int log: 1; /* 1 if this is a control connection requesting log dump */
|
unsigned int 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: 1; /* 1 if this is an invitation */
|
||||||
unsigned int invitation_used: 1; /* 1 if the invitation has been consumed */
|
unsigned int invitation_used: 1; /* 1 if the invitation has been consumed */
|
||||||
unsigned int unused:18;
|
unsigned int tarpit: 1; /* 1 if the connection should be added to the tarpit */
|
||||||
|
unsigned int unused: 17;
|
||||||
} connection_status_t;
|
} connection_status_t;
|
||||||
|
|
||||||
#include "ecdsa.h"
|
#include "ecdsa.h"
|
||||||
|
@ -94,6 +95,7 @@ typedef struct connection_t {
|
||||||
int outcompression;
|
int outcompression;
|
||||||
|
|
||||||
char *hischallenge; /* The challenge we sent to him */
|
char *hischallenge; /* The challenge we sent to him */
|
||||||
|
char *mychallenge; /* The challenge we received */
|
||||||
|
|
||||||
struct buffer_t inbuf;
|
struct buffer_t inbuf;
|
||||||
struct buffer_t outbuf;
|
struct buffer_t outbuf;
|
||||||
|
@ -113,9 +115,9 @@ extern connection_t *everyone;
|
||||||
extern void init_connections(void);
|
extern void init_connections(void);
|
||||||
extern void exit_connections(void);
|
extern void exit_connections(void);
|
||||||
extern connection_t *new_connection(void) __attribute__((__malloc__));
|
extern connection_t *new_connection(void) __attribute__((__malloc__));
|
||||||
extern void free_connection(connection_t *);
|
extern void free_connection(connection_t *c);
|
||||||
extern void connection_add(connection_t *);
|
extern void connection_add(connection_t *c);
|
||||||
extern void connection_del(connection_t *);
|
extern void connection_del(connection_t *c);
|
||||||
extern bool dump_connections(struct connection_t *);
|
extern bool dump_connections(struct connection_t *c);
|
||||||
|
|
||||||
#endif /* __TINC_CONNECTION_H__ */
|
#endif
|
||||||
|
|
|
@ -79,11 +79,17 @@ bool control_h(connection_t *c, const char *request) {
|
||||||
|
|
||||||
case REQ_SET_DEBUG: {
|
case REQ_SET_DEBUG: {
|
||||||
int new_level;
|
int new_level;
|
||||||
if(sscanf(request, "%*d %*d %d", &new_level) != 1)
|
|
||||||
|
if(sscanf(request, "%*d %*d %d", &new_level) != 1) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
send_request(c, "%d %d %d", CONTROL, REQ_SET_DEBUG, debug_level);
|
send_request(c, "%d %d %d", CONTROL, REQ_SET_DEBUG, debug_level);
|
||||||
if(new_level >= 0)
|
|
||||||
|
if(new_level >= 0) {
|
||||||
debug_level = new_level;
|
debug_level = new_level;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,12 +106,15 @@ bool control_h(connection_t *c, const char *request) {
|
||||||
char name[MAX_STRING_SIZE];
|
char name[MAX_STRING_SIZE];
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
if(sscanf(request, "%*d %*d " MAX_STRING, name) != 1)
|
if(sscanf(request, "%*d %*d " MAX_STRING, name) != 1) {
|
||||||
return control_return(c, REQ_DISCONNECT, -1);
|
return control_return(c, REQ_DISCONNECT, -1);
|
||||||
|
}
|
||||||
|
|
||||||
for list_each(connection_t, other, connection_list) {
|
for list_each(connection_t, other, connection_list) {
|
||||||
if(strcmp(other->name, name))
|
if(strcmp(other->name, name)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
terminate_connection(other, other->edge);
|
terminate_connection(other, other->edge);
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
|
@ -134,8 +143,8 @@ bool control_h(connection_t *c, const char *request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool init_control(void) {
|
bool init_control(void) {
|
||||||
randomize(controlcookie, sizeof controlcookie / 2);
|
randomize(controlcookie, sizeof(controlcookie) / 2);
|
||||||
bin2hex(controlcookie, controlcookie, sizeof controlcookie / 2);
|
bin2hex(controlcookie, controlcookie, sizeof(controlcookie) / 2);
|
||||||
|
|
||||||
mode_t mask = umask(0);
|
mode_t mask = umask(0);
|
||||||
umask(mask | 077);
|
umask(mask | 077);
|
||||||
|
@ -150,22 +159,25 @@ bool init_control(void) {
|
||||||
// Get the address and port of the first listening socket
|
// Get the address and port of the first listening socket
|
||||||
|
|
||||||
char *localhost = NULL;
|
char *localhost = NULL;
|
||||||
sockaddr_t sa;
|
sockaddr_t sa = {0};
|
||||||
socklen_t len = sizeof sa;
|
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.
|
// 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);
|
xasprintf(&localhost, "127.0.0.1 port %s", myport);
|
||||||
} else {
|
} else {
|
||||||
if(sa.sa.sa_family == AF_INET) {
|
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);
|
sa.in.sin_addr.s_addr = htonl(0x7f000001);
|
||||||
|
}
|
||||||
} else if(sa.sa.sa_family == AF_INET6) {
|
} else if(sa.sa.sa_family == AF_INET6) {
|
||||||
static const uint8_t zero[16] = {0};
|
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;
|
sa.in6.sin6_addr.s6_addr[15] = 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
localhost = sockaddr2hostname(&sa);
|
localhost = sockaddr2hostname(&sa);
|
||||||
}
|
}
|
||||||
|
@ -177,16 +189,21 @@ bool init_control(void) {
|
||||||
|
|
||||||
#ifndef HAVE_MINGW
|
#ifndef HAVE_MINGW
|
||||||
int unix_fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
int unix_fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
|
||||||
if(unix_fd < 0) {
|
if(unix_fd < 0) {
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "Could not create UNIX socket: %s", sockstrerror(sockerrno));
|
logger(DEBUG_ALWAYS, LOG_ERR, "Could not create UNIX socket: %s", sockstrerror(sockerrno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sockaddr_un sa_un;
|
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);
|
logger(DEBUG_ALWAYS, LOG_ERR, "UNIX socket %s is still in use!", unixsocketname);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -194,7 +211,7 @@ bool init_control(void) {
|
||||||
unlink(unixsocketname);
|
unlink(unixsocketname);
|
||||||
|
|
||||||
umask(mask | 077);
|
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);
|
umask(mask);
|
||||||
|
|
||||||
if(result < 0) {
|
if(result < 0) {
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
#ifndef TINC_CONTROL_H
|
||||||
|
#define TINC_CONTROL_H
|
||||||
|
|
||||||
/*
|
/*
|
||||||
control.h -- header for control.c.
|
control.h -- header for control.c.
|
||||||
Copyright (C) 2007 Guus Sliepen <guus@tinc-vpn.org>
|
Copyright (C) 2007 Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
@ -17,11 +20,8 @@
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TINC_CONTROL_H__
|
extern bool init_control(void);
|
||||||
#define __TINC_CONTROL_H__
|
extern void exit_control(void);
|
||||||
|
|
||||||
extern bool init_control();
|
|
||||||
extern void exit_control();
|
|
||||||
extern char controlcookie[];
|
extern char controlcookie[];
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
#ifndef TINC_CONTROL_COMMON_H
|
||||||
|
#define TINC_CONTROL_COMMON_H
|
||||||
|
|
||||||
/*
|
/*
|
||||||
control_protocol.h -- control socket protocol.
|
control_protocol.h -- control socket protocol.
|
||||||
Copyright (C) 2007 Scott Lamb <slamb@slamb.org>
|
Copyright (C) 2007 Scott Lamb <slamb@slamb.org>
|
||||||
|
@ -18,9 +21,6 @@
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TINC_CONTROL_PROTOCOL_H__
|
|
||||||
#define __TINC_CONTROL_PROTOCOL_H__
|
|
||||||
|
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
|
|
||||||
enum request_type {
|
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
|
crypto.h -- header for crypto.c
|
||||||
Copyright (C) 2007-2013 Guus Sliepen <guus@tinc-vpn.org>
|
Copyright (C) 2007-2013 Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
@ -17,11 +20,8 @@
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TINC_CRYPTO_H__
|
extern void crypto_init(void);
|
||||||
#define __TINC_CRYPTO_H__
|
extern void crypto_exit(void);
|
||||||
|
extern void randomize(void *buf, size_t buflen);
|
||||||
extern void crypto_init();
|
|
||||||
extern void crypto_exit();
|
|
||||||
extern void randomize(void *, size_t);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -38,7 +38,7 @@ int device_fd = -1;
|
||||||
static HANDLE device_handle = INVALID_HANDLE_VALUE;
|
static HANDLE device_handle = INVALID_HANDLE_VALUE;
|
||||||
char *device = NULL;
|
char *device = NULL;
|
||||||
char *iface = NULL;
|
char *iface = NULL;
|
||||||
static char *device_info = NULL;
|
static const char *device_info = "Windows tap device";
|
||||||
|
|
||||||
static pid_t reader_pid;
|
static pid_t reader_pid;
|
||||||
static int sp[2];
|
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, "Device"), &device);
|
||||||
get_config_string(lookup_config(config_tree, "Interface"), &iface);
|
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");
|
logger(LOG_WARNING, "Warning: both Device and Interface specified, results may not be as expected");
|
||||||
|
}
|
||||||
|
|
||||||
/* Open registry and look for network adapters */
|
/* Open registry and look for network adapters */
|
||||||
|
|
||||||
|
@ -70,43 +71,50 @@ static bool setup_device(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; ; i++) {
|
for(i = 0; ; i++) {
|
||||||
len = sizeof adapterid;
|
len = sizeof(adapterid);
|
||||||
if(RegEnumKeyEx(key, i, adapterid, &len, 0, 0, 0, NULL))
|
|
||||||
|
if(RegEnumKeyEx(key, i, adapterid, &len, 0, 0, 0, NULL)) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Find out more about this adapter */
|
/* 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;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
len = sizeof adaptername;
|
len = sizeof(adaptername);
|
||||||
err = RegQueryValueEx(key2, "Name", 0, 0, adaptername, &len);
|
err = RegQueryValueEx(key2, "Name", 0, 0, adaptername, &len);
|
||||||
|
|
||||||
RegCloseKey(key2);
|
RegCloseKey(key2);
|
||||||
|
|
||||||
if(err)
|
if(err) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if(device) {
|
if(device) {
|
||||||
if(!strcmp(device, adapterid)) {
|
if(!strcmp(device, adapterid)) {
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
} else
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(iface) {
|
if(iface) {
|
||||||
if(!strcmp(iface, adaptername)) {
|
if(!strcmp(iface, adaptername)) {
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
} else
|
} else {
|
||||||
continue;
|
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);
|
device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0);
|
||||||
|
|
||||||
if(device_handle != INVALID_HANDLE_VALUE) {
|
if(device_handle != INVALID_HANDLE_VALUE) {
|
||||||
CloseHandle(device_handle);
|
CloseHandle(device_handle);
|
||||||
found = true;
|
found = true;
|
||||||
|
@ -121,13 +129,15 @@ static bool setup_device(void) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!device)
|
if(!device) {
|
||||||
device = xstrdup(adapterid);
|
device = xstrdup(adapterid);
|
||||||
|
}
|
||||||
|
|
||||||
if(!iface)
|
if(!iface) {
|
||||||
iface = xstrdup(adaptername);
|
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.
|
/* 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.
|
We do this because apparently it isn't possible to check for activity in the select() loop.
|
||||||
|
@ -151,7 +161,7 @@ static bool setup_device(void) {
|
||||||
|
|
||||||
/* Get MAC address from tap device */
|
/* 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()));
|
logger(DEBUG_ALWAYS, LOG_ERR, "Could not get MAC address from Windows tap device %s (%s): %s", device, iface, winerror(GetLastError()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -203,13 +213,12 @@ static bool setup_device(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
read(device_fd, &gelukt, 1);
|
read(device_fd, &gelukt, 1);
|
||||||
|
|
||||||
if(gelukt != 1) {
|
if(gelukt != 1) {
|
||||||
logger(DEBUG_ALWAYS, LOG_DEBUG, "Tap reader failed!");
|
logger(DEBUG_ALWAYS, LOG_DEBUG, "Tap reader failed!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
device_info = "Windows tap device";
|
|
||||||
|
|
||||||
logger(DEBUG_ALWAYS, LOG_INFO, "%s (%s) is a %s", device, iface, device_info);
|
logger(DEBUG_ALWAYS, LOG_INFO, "%s (%s) is a %s", device, iface, device_info);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -218,12 +227,15 @@ static bool setup_device(void) {
|
||||||
static void close_device(void) {
|
static void close_device(void) {
|
||||||
close(sp[0]);
|
close(sp[0]);
|
||||||
close(sp[1]);
|
close(sp[1]);
|
||||||
CloseHandle(device_handle); device_handle = INVALID_HANDLE_VALUE;
|
CloseHandle(device_handle);
|
||||||
|
device_handle = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
kill(reader_pid, SIGKILL);
|
kill(reader_pid, SIGKILL);
|
||||||
|
|
||||||
free(device); device = NULL;
|
free(device);
|
||||||
free(iface); iface = NULL;
|
device = NULL;
|
||||||
|
free(iface);
|
||||||
|
iface = NULL;
|
||||||
device_info = NULL;
|
device_info = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
#ifndef TINC_DEVICE_H
|
||||||
|
#define TINC_DEVICE_H
|
||||||
|
|
||||||
/*
|
/*
|
||||||
device.h -- generic header for device.c
|
device.h -- generic header for device.c
|
||||||
Copyright (C) 2001-2005 Ivo Timmermans
|
Copyright (C) 2001-2005 Ivo Timmermans
|
||||||
|
@ -18,9 +21,6 @@
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TINC_DEVICE_H__
|
|
||||||
#define __TINC_DEVICE_H__
|
|
||||||
|
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
|
|
||||||
extern int device_fd;
|
extern int device_fd;
|
||||||
|
@ -45,4 +45,4 @@ extern const devops_t uml_devops;
|
||||||
extern const devops_t vde_devops;
|
extern const devops_t vde_devops;
|
||||||
extern devops_t devops;
|
extern devops_t devops;
|
||||||
|
|
||||||
#endif /* __TINC_DEVICE_H__ */
|
#endif
|
||||||
|
|
22
src/digest.h
22
src/digest.h
|
@ -1,3 +1,6 @@
|
||||||
|
#ifndef TINC_DIGEST_H
|
||||||
|
#define TINC_DIGEST_H
|
||||||
|
|
||||||
/*
|
/*
|
||||||
digest.h -- header file digest.c
|
digest.h -- header file digest.c
|
||||||
Copyright (C) 2007-2016 Guus Sliepen <guus@tinc-vpn.org>
|
Copyright (C) 2007-2016 Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
@ -17,9 +20,6 @@
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TINC_DIGEST_H__
|
|
||||||
#define __TINC_DIGEST_H__
|
|
||||||
|
|
||||||
#define DIGEST_MAX_SIZE 64
|
#define DIGEST_MAX_SIZE 64
|
||||||
|
|
||||||
#ifndef DISABLE_LEGACY
|
#ifndef DISABLE_LEGACY
|
||||||
|
@ -28,14 +28,14 @@ typedef struct digest digest_t;
|
||||||
|
|
||||||
extern digest_t *digest_open_by_name(const char *name, int maclength) __attribute__((__malloc__));
|
extern digest_t *digest_open_by_name(const char *name, int maclength) __attribute__((__malloc__));
|
||||||
extern digest_t *digest_open_by_nid(int nid, int maclength) __attribute__((__malloc__));
|
extern digest_t *digest_open_by_nid(int nid, int maclength) __attribute__((__malloc__));
|
||||||
extern void digest_close(digest_t *);
|
extern void digest_close(digest_t *digest);
|
||||||
extern bool digest_create(digest_t *, const void *indata, size_t inlen, void *outdata) __attribute__ ((__warn_unused_result__));
|
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 *, const void *indata, size_t inlen, const void *digestdata) __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 *, const void *key, size_t len) __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 *);
|
extern int digest_get_nid(const digest_t *digest);
|
||||||
extern size_t digest_keylength(const digest_t *);
|
extern size_t digest_keylength(const digest_t *digest);
|
||||||
extern size_t digest_length(const digest_t *);
|
extern size_t digest_length(const digest_t *digest);
|
||||||
extern bool digest_active(const digest_t *);
|
extern bool digest_active(const digest_t *digest);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -50,8 +50,9 @@ int daemon(int nochdir, int noclose) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we are the parent, terminate */
|
/* If we are the parent, terminate */
|
||||||
if(pid)
|
if(pid) {
|
||||||
exit(0);
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Detach by becoming the new process group leader */
|
/* Detach by becoming the new process group leader */
|
||||||
if(setsid() < 0) {
|
if(setsid() < 0) {
|
||||||
|
@ -108,8 +109,9 @@ int vasprintf(char **buf, const char *fmt, va_list ap) {
|
||||||
status = vsnprintf(*buf, len, fmt, aq);
|
status = vsnprintf(*buf, len, fmt, aq);
|
||||||
va_end(aq);
|
va_end(aq);
|
||||||
|
|
||||||
if(status >= 0)
|
if(status >= 0) {
|
||||||
*buf = xrealloc(*buf, status + 1);
|
*buf = xrealloc(*buf, status + 1);
|
||||||
|
}
|
||||||
|
|
||||||
if(status > len - 1) {
|
if(status > len - 1) {
|
||||||
len = status + 1;
|
len = status + 1;
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
#ifndef TINC_DROPIN_H
|
||||||
|
#define TINC_DROPIN_H
|
||||||
|
|
||||||
/*
|
/*
|
||||||
dropin.h -- header file for dropin.c
|
dropin.h -- header file for dropin.c
|
||||||
Copyright (C) 2000-2005 Ivo Timmermans,
|
Copyright (C) 2000-2005 Ivo Timmermans,
|
||||||
|
@ -18,9 +21,6 @@
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __DROPIN_H__
|
|
||||||
#define __DROPIN_H__
|
|
||||||
|
|
||||||
#ifndef HAVE_DAEMON
|
#ifndef HAVE_DAEMON
|
||||||
extern int daemon(int, int);
|
extern int daemon(int, int);
|
||||||
#endif
|
#endif
|
||||||
|
@ -67,4 +67,4 @@ extern int nanosleep(const struct timespec *req, struct timespec *rem);
|
||||||
#define EAI_SYSTEM 0
|
#define EAI_SYSTEM 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __DROPIN_H__ */
|
#endif
|
||||||
|
|
|
@ -22,12 +22,13 @@
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "net.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) {
|
static bool setup_device(void) {
|
||||||
device = "dummy";
|
device = xstrdup("dummy");
|
||||||
iface = "dummy";
|
iface = xstrdup("dummy");
|
||||||
logger(DEBUG_ALWAYS, LOG_INFO, "%s (%s) is a %s", device, iface, device_info);
|
logger(DEBUG_ALWAYS, LOG_INFO, "%s (%s) is a %s", device, iface, device_info);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -36,10 +37,12 @@ static void close_device(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool read_packet(vpn_packet_t *packet) {
|
static bool read_packet(vpn_packet_t *packet) {
|
||||||
|
(void)packet;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool write_packet(vpn_packet_t *packet) {
|
static bool write_packet(vpn_packet_t *packet) {
|
||||||
|
(void)packet;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
#ifndef TINC_ECDH_H
|
||||||
|
#define TINC_ECDH_H
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ecdh.h -- header file for ecdh.c
|
ecdh.h -- header file for ecdh.c
|
||||||
Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org>
|
Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
@ -17,13 +20,10 @@
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TINC_ECDH_H__
|
|
||||||
#define __TINC_ECDH_H__
|
|
||||||
|
|
||||||
#define ECDH_SIZE 32
|
#define ECDH_SIZE 32
|
||||||
#define ECDH_SHARED_SIZE 32
|
#define ECDH_SHARED_SIZE 32
|
||||||
|
|
||||||
#ifndef __TINC_ECDH_INTERNAL__
|
#ifndef TINC_ECDH_INTERNAL
|
||||||
typedef struct ecdh ecdh_t;
|
typedef struct ecdh ecdh_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
#ifndef TINC_ECDSA_H
|
||||||
|
#define TINC_ECDSA_H
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ecdsa.h -- ECDSA key handling
|
ecdsa.h -- ECDSA key handling
|
||||||
Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org>
|
Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
@ -17,10 +20,7 @@
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TINC_ECDSA_H__
|
#ifndef TINC_ECDSA_INTERNAL
|
||||||
#define __TINC_ECDSA_H__
|
|
||||||
|
|
||||||
#ifndef __TINC_ECDSA_INTERNAL__
|
|
||||||
typedef struct ecdsa ecdsa_t;
|
typedef struct ecdsa ecdsa_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
#ifndef TINC_ECDSAGEN_H
|
||||||
|
#define TINC_ECDSAGEN_H
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ecdsagen.h -- ECDSA key generation and export
|
ecdsagen.h -- ECDSA key generation and export
|
||||||
Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org>
|
Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
@ -17,9 +20,6 @@
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TINC_ECDSAGEN_H__
|
|
||||||
#define __TINC_ECDSAGEN_H__
|
|
||||||
|
|
||||||
#include "ecdsa.h"
|
#include "ecdsa.h"
|
||||||
|
|
||||||
extern ecdsa_t *ecdsa_generate(void) __attribute__((__malloc__));
|
extern ecdsa_t *ecdsa_generate(void) __attribute__((__malloc__));
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
#include "ed25519.h"
|
#include "ed25519.h"
|
||||||
|
|
||||||
#define __TINC_ECDH_INTERNAL__
|
#define TINC_ECDH_INTERNAL
|
||||||
typedef struct ecdh_t {
|
typedef struct ecdh_t {
|
||||||
uint8_t private[64];
|
uint8_t private[64];
|
||||||
} ecdh_t;
|
} ecdh_t;
|
||||||
|
@ -31,10 +31,10 @@ typedef struct ecdh_t {
|
||||||
#include "../xalloc.h"
|
#include "../xalloc.h"
|
||||||
|
|
||||||
ecdh_t *ecdh_generate_public(void *pubkey) {
|
ecdh_t *ecdh_generate_public(void *pubkey) {
|
||||||
ecdh_t *ecdh = xzalloc(sizeof *ecdh);
|
ecdh_t *ecdh = xzalloc(sizeof(*ecdh));
|
||||||
|
|
||||||
uint8_t seed[32];
|
uint8_t seed[32];
|
||||||
randomize(seed, sizeof seed);
|
randomize(seed, sizeof(seed));
|
||||||
ed25519_create_keypair(pubkey, ecdh->private, seed);
|
ed25519_create_keypair(pubkey, ecdh->private, seed);
|
||||||
|
|
||||||
return ecdh;
|
return ecdh;
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
#include "ed25519.h"
|
#include "ed25519.h"
|
||||||
|
|
||||||
#define __TINC_ECDSA_INTERNAL__
|
#define TINC_ECDSA_INTERNAL
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t private[64];
|
uint8_t private[64];
|
||||||
uint8_t public[32];
|
uint8_t public[32];
|
||||||
|
@ -42,8 +42,9 @@ ecdsa_t *ecdsa_set_base64_public_key(const char *p) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ecdsa_t *ecdsa = xzalloc(sizeof *ecdsa);
|
ecdsa_t *ecdsa = xzalloc(sizeof(*ecdsa));
|
||||||
len = b64decode(p, ecdsa->public, len);
|
len = b64decode(p, ecdsa->public, len);
|
||||||
|
|
||||||
if(len != 32) {
|
if(len != 32) {
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "Invalid format of public key! len = %d", len);
|
logger(DEBUG_ALWAYS, LOG_ERR, "Invalid format of public key! len = %d", len);
|
||||||
free(ecdsa);
|
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 *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) {
|
||||||
char *base64 = xmalloc(44);
|
char *base64 = xmalloc(44);
|
||||||
b64encode(ecdsa->public, base64, sizeof ecdsa->public);
|
b64encode(ecdsa->public, base64, sizeof(ecdsa->public));
|
||||||
|
|
||||||
return base64;
|
return base64;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read PEM ECDSA keys
|
// 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];
|
char line[1024];
|
||||||
bool data = false;
|
bool data = false;
|
||||||
size_t typelen = strlen(type);
|
size_t typelen = strlen(type);
|
||||||
|
char *buf = vbuf;
|
||||||
|
|
||||||
while(fgets(line, sizeof line, fp)) {
|
while(fgets(line, sizeof(line), fp)) {
|
||||||
if(!data) {
|
if(!data) {
|
||||||
if(strncmp(line, "-----BEGIN ", 11))
|
if(strncmp(line, "-----BEGIN ", 11)) {
|
||||||
continue;
|
continue;
|
||||||
if(strncmp(line + 11, type, typelen))
|
}
|
||||||
|
|
||||||
|
if(strncmp(line + 11, type, typelen)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
data = true;
|
data = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!strncmp(line, "-----END ", 9))
|
if(!strncmp(line, "-----END ", 9)) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
size_t linelen = strcspn(line, "\r\n");
|
size_t linelen = strcspn(line, "\r\n");
|
||||||
size_t len = b64decode(line, line, linelen);
|
size_t len = b64decode(line, line, linelen);
|
||||||
|
|
||||||
if(!len) {
|
if(!len) {
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "Invalid base64 data in PEM file\n");
|
logger(DEBUG_ALWAYS, LOG_ERR, "Invalid base64 data in PEM file\n");
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
|
@ -106,6 +114,7 @@ static bool read_pem(FILE *fp, const char *type, void *buf, size_t size) {
|
||||||
} else {
|
} else {
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
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_read_pem_public_key(FILE *fp) {
|
||||||
ecdsa_t *ecdsa = xzalloc(sizeof *ecdsa);
|
ecdsa_t *ecdsa = xzalloc(sizeof(*ecdsa));
|
||||||
if(read_pem(fp, "ED25519 PUBLIC KEY", ecdsa->public, sizeof ecdsa->public))
|
|
||||||
|
if(read_pem(fp, "ED25519 PUBLIC KEY", ecdsa->public, sizeof(ecdsa->public))) {
|
||||||
return ecdsa;
|
return ecdsa;
|
||||||
|
}
|
||||||
|
|
||||||
free(ecdsa);
|
free(ecdsa);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) {
|
ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) {
|
||||||
ecdsa_t *ecdsa = xmalloc(sizeof *ecdsa);
|
ecdsa_t *ecdsa = xmalloc(sizeof(*ecdsa));
|
||||||
if(read_pem(fp, "ED25519 PRIVATE KEY", ecdsa->private, sizeof *ecdsa))
|
|
||||||
|
if(read_pem(fp, "ED25519 PRIVATE KEY", ecdsa->private, sizeof(*ecdsa))) {
|
||||||
return ecdsa;
|
return ecdsa;
|
||||||
|
}
|
||||||
|
|
||||||
free(ecdsa);
|
free(ecdsa);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ecdsa_size(ecdsa_t *ecdsa) {
|
size_t ecdsa_size(ecdsa_t *ecdsa) {
|
||||||
|
(void)ecdsa;
|
||||||
return 64;
|
return 64;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
#include "ed25519.h"
|
#include "ed25519.h"
|
||||||
|
|
||||||
#define __TINC_ECDSA_INTERNAL__
|
#define TINC_ECDSA_INTERNAL
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t private[64];
|
uint8_t private[64];
|
||||||
uint8_t public[32];
|
uint8_t public[32];
|
||||||
|
@ -35,10 +35,10 @@ typedef struct {
|
||||||
// Generate ECDSA key
|
// Generate ECDSA key
|
||||||
|
|
||||||
ecdsa_t *ecdsa_generate(void) {
|
ecdsa_t *ecdsa_generate(void) {
|
||||||
ecdsa_t *ecdsa = xzalloc(sizeof *ecdsa);
|
ecdsa_t *ecdsa = xzalloc(sizeof(*ecdsa));
|
||||||
|
|
||||||
uint8_t seed[32];
|
uint8_t seed[32];
|
||||||
randomize(seed, sizeof seed);
|
randomize(seed, sizeof(seed));
|
||||||
ed25519_create_keypair(ecdsa->public, ecdsa->private, seed);
|
ed25519_create_keypair(ecdsa->public, ecdsa->private, seed);
|
||||||
|
|
||||||
return ecdsa;
|
return ecdsa;
|
||||||
|
@ -46,10 +46,12 @@ ecdsa_t *ecdsa_generate(void) {
|
||||||
|
|
||||||
// Write PEM ECDSA keys
|
// 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);
|
fprintf(fp, "-----BEGIN %s-----\n", type);
|
||||||
|
|
||||||
|
char *buf = vbuf;
|
||||||
char base64[65];
|
char base64[65];
|
||||||
|
|
||||||
while(size) {
|
while(size) {
|
||||||
size_t todo = size > 48 ? 48 : size;
|
size_t todo = size > 48 ? 48 : size;
|
||||||
b64encode(buf, base64, todo);
|
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) {
|
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) {
|
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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -808,17 +808,37 @@ void fe_mul121666(fe h, fe f) {
|
||||||
int64_t carry8;
|
int64_t carry8;
|
||||||
int64_t carry9;
|
int64_t carry9;
|
||||||
|
|
||||||
carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= shl64(carry9, 25);
|
carry9 = (h9 + (int64_t)(1 << 24)) >> 25;
|
||||||
carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= shl64(carry1, 25);
|
h0 += carry9 * 19;
|
||||||
carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= shl64(carry3, 25);
|
h9 -= shl64(carry9, 25);
|
||||||
carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= shl64(carry5, 25);
|
carry1 = (h1 + (int64_t)(1 << 24)) >> 25;
|
||||||
carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= shl64(carry7, 25);
|
h2 += carry1;
|
||||||
|
h1 -= shl64(carry1, 25);
|
||||||
|
carry3 = (h3 + (int64_t)(1 << 24)) >> 25;
|
||||||
|
h4 += carry3;
|
||||||
|
h3 -= shl64(carry3, 25);
|
||||||
|
carry5 = (h5 + (int64_t)(1 << 24)) >> 25;
|
||||||
|
h6 += carry5;
|
||||||
|
h5 -= shl64(carry5, 25);
|
||||||
|
carry7 = (h7 + (int64_t)(1 << 24)) >> 25;
|
||||||
|
h8 += carry7;
|
||||||
|
h7 -= shl64(carry7, 25);
|
||||||
|
|
||||||
carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= shl64(carry0, 26);
|
carry0 = (h0 + (int64_t)(1 << 25)) >> 26;
|
||||||
carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= shl64(carry2, 26);
|
h1 += carry0;
|
||||||
carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= shl64(carry4, 26);
|
h0 -= shl64(carry0, 26);
|
||||||
carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= shl64(carry6, 26);
|
carry2 = (h2 + (int64_t)(1 << 25)) >> 26;
|
||||||
carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= shl64(carry8, 26);
|
h3 += carry2;
|
||||||
|
h2 -= shl64(carry2, 26);
|
||||||
|
carry4 = (h4 + (int64_t)(1 << 25)) >> 26;
|
||||||
|
h5 += carry4;
|
||||||
|
h4 -= shl64(carry4, 26);
|
||||||
|
carry6 = (h6 + (int64_t)(1 << 25)) >> 26;
|
||||||
|
h7 += carry6;
|
||||||
|
h6 -= shl64(carry6, 26);
|
||||||
|
carry8 = (h8 + (int64_t)(1 << 25)) >> 26;
|
||||||
|
h9 += carry8;
|
||||||
|
h8 -= shl64(carry8, 26);
|
||||||
|
|
||||||
h[0] = h0;
|
h[0] = h0;
|
||||||
h[1] = h1;
|
h[1] = h1;
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
|
#ifndef TINC_FIXEDINT_H
|
||||||
|
#define TINC_FIXEDINT_H
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Portable header to provide the 32 and 64 bits type.
|
Portable header to provide the 32 and 64 bits type.
|
||||||
|
|
||||||
Not a compatible replacement for <stdint.h>, do not blindly use it as such.
|
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)
|
#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>
|
#include <stdint.h>
|
||||||
#define FIXEDINT_H_INCLUDED
|
#define FIXEDINT_H_INCLUDED
|
||||||
|
|
|
@ -41,6 +41,7 @@ void ed25519_key_exchange(unsigned char *shared_secret, const unsigned char *pub
|
||||||
fe_1(z3);
|
fe_1(z3);
|
||||||
|
|
||||||
swap = 0;
|
swap = 0;
|
||||||
|
|
||||||
for(pos = 254; pos >= 0; --pos) {
|
for(pos = 254; pos >= 0; --pos) {
|
||||||
b = e[pos / 8] >> (pos & 7);
|
b = e[pos / 8] >> (pos & 7);
|
||||||
b &= 1;
|
b &= 1;
|
||||||
|
|
|
@ -88,8 +88,7 @@ static const uint64_t K[80] = {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* compress 1024-bits */
|
/* compress 1024-bits */
|
||||||
static int sha512_compress(sha512_context *md, const unsigned char *buf)
|
static int sha512_compress(sha512_context *md, const unsigned char *buf) {
|
||||||
{
|
|
||||||
uint64_t S[8], W[80], t0, t1;
|
uint64_t S[8], W[80], t0, t1;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -145,7 +144,9 @@ static int sha512_compress(sha512_context *md, const unsigned char *buf)
|
||||||
@return 0 if successful
|
@return 0 if successful
|
||||||
*/
|
*/
|
||||||
int sha512_init(sha512_context *md) {
|
int sha512_init(sha512_context *md) {
|
||||||
if (md == NULL) return 1;
|
if(md == NULL) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
md->curlen = 0;
|
md->curlen = 0;
|
||||||
md->length = 0;
|
md->length = 0;
|
||||||
|
@ -168,22 +169,30 @@ int sha512_init(sha512_context * md) {
|
||||||
@param inlen The length of the data (octets)
|
@param inlen The length of the data (octets)
|
||||||
@return 0 if successful
|
@return 0 if successful
|
||||||
*/
|
*/
|
||||||
int sha512_update(sha512_context *md, const void *vin, size_t inlen)
|
int sha512_update(sha512_context *md, const void *vin, size_t inlen) {
|
||||||
{
|
|
||||||
const unsigned char *in = vin;
|
const unsigned char *in = vin;
|
||||||
size_t n;
|
size_t n;
|
||||||
size_t i;
|
size_t i;
|
||||||
int err;
|
int err;
|
||||||
if (md == NULL) return 1;
|
|
||||||
if (in == NULL) return 1;
|
if(md == NULL) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(in == NULL) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if(md->curlen > sizeof(md->buf)) {
|
if(md->curlen > sizeof(md->buf)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while(inlen > 0) {
|
while(inlen > 0) {
|
||||||
if(md->curlen == 0 && inlen >= 128) {
|
if(md->curlen == 0 && inlen >= 128) {
|
||||||
if((err = sha512_compress(md, in)) != 0) {
|
if((err = sha512_compress(md, in)) != 0) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
md->length += 128 * 8;
|
md->length += 128 * 8;
|
||||||
in += 128;
|
in += 128;
|
||||||
inlen -= 128;
|
inlen -= 128;
|
||||||
|
@ -198,15 +207,18 @@ int sha512_update(sha512_context *md, const void *vin, size_t inlen)
|
||||||
md->curlen += n;
|
md->curlen += n;
|
||||||
in += n;
|
in += n;
|
||||||
inlen -= n;
|
inlen -= n;
|
||||||
|
|
||||||
if(md->curlen == 128) {
|
if(md->curlen == 128) {
|
||||||
if((err = sha512_compress(md, md->buf)) != 0) {
|
if((err = sha512_compress(md, md->buf)) != 0) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
md->length += 8 * 128;
|
md->length += 8 * 128;
|
||||||
md->curlen = 0;
|
md->curlen = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,13 +228,17 @@ int sha512_update(sha512_context *md, const void *vin, size_t inlen)
|
||||||
@param out [out] The destination of the hash (64 bytes)
|
@param out [out] The destination of the hash (64 bytes)
|
||||||
@return 0 if successful
|
@return 0 if successful
|
||||||
*/
|
*/
|
||||||
int sha512_final(sha512_context * md, void *vout)
|
int sha512_final(sha512_context *md, void *vout) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
unsigned char *out = vout;
|
unsigned char *out = vout;
|
||||||
|
|
||||||
if (md == NULL) return 1;
|
if(md == NULL) {
|
||||||
if (out == NULL) return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(out == NULL) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if(md->curlen >= sizeof(md->buf)) {
|
if(md->curlen >= sizeof(md->buf)) {
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -242,6 +258,7 @@ int sha512_final(sha512_context * md, void *vout)
|
||||||
while(md->curlen < 128) {
|
while(md->curlen < 128) {
|
||||||
md->buf[md->curlen++] = (unsigned char)0;
|
md->buf[md->curlen++] = (unsigned char)0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sha512_compress(md, md->buf);
|
sha512_compress(md, md->buf);
|
||||||
md->curlen = 0;
|
md->curlen = 0;
|
||||||
}
|
}
|
||||||
|
@ -266,12 +283,21 @@ int sha512_final(sha512_context * md, void *vout)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sha512(const void *message, size_t message_len, void *out)
|
int sha512(const void *message, size_t message_len, void *out) {
|
||||||
{
|
|
||||||
sha512_context ctx;
|
sha512_context ctx;
|
||||||
int ret;
|
int ret;
|
||||||
if ((ret = sha512_init(&ctx))) return ret;
|
|
||||||
if ((ret = sha512_update(&ctx, message, message_len))) return ret;
|
if((ret = sha512_init(&ctx))) {
|
||||||
if ((ret = sha512_final(&ctx, out))) return ret;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((ret = sha512_update(&ctx, message, message_len))) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((ret = sha512_final(&ctx, out))) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
12
src/edge.c
12
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;
|
result = a->weight - b->weight;
|
||||||
|
|
||||||
if(result)
|
if(result) {
|
||||||
return result;
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
result = strcmp(a->from->name, b->from->name);
|
result = strcmp(a->from->name, b->from->name);
|
||||||
|
|
||||||
if(result)
|
if(result) {
|
||||||
return result;
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
return strcmp(a->to->name, b->to->name);
|
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);
|
e->reverse = lookup_edge(e->to, e->from);
|
||||||
|
|
||||||
if(e->reverse)
|
if(e->reverse) {
|
||||||
e->reverse->reverse = e;
|
e->reverse->reverse = e;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void edge_del(edge_t *e) {
|
void edge_del(edge_t *e) {
|
||||||
if(e->reverse)
|
if(e->reverse) {
|
||||||
e->reverse->reverse = NULL;
|
e->reverse->reverse = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
splay_delete(edge_weight_tree, e);
|
splay_delete(edge_weight_tree, e);
|
||||||
splay_delete(e->from->edge_tree, e);
|
splay_delete(e->from->edge_tree, e);
|
||||||
|
|
20
src/edge.h
20
src/edge.h
|
@ -1,3 +1,6 @@
|
||||||
|
#ifndef TINC_EDGE_H
|
||||||
|
#define TINC_EDGE_H
|
||||||
|
|
||||||
/*
|
/*
|
||||||
edge.h -- header for edge.c
|
edge.h -- header for edge.c
|
||||||
Copyright (C) 2001-2012 Guus Sliepen <guus@tinc-vpn.org>,
|
Copyright (C) 2001-2012 Guus Sliepen <guus@tinc-vpn.org>,
|
||||||
|
@ -18,9 +21,6 @@
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TINC_EDGE_H__
|
|
||||||
#define __TINC_EDGE_H__
|
|
||||||
|
|
||||||
#include "splay_tree.h"
|
#include "splay_tree.h"
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
|
@ -44,12 +44,12 @@ extern splay_tree_t *edge_weight_tree; /* Tree with all known edges sor
|
||||||
extern void init_edges(void);
|
extern void init_edges(void);
|
||||||
extern void exit_edges(void);
|
extern void exit_edges(void);
|
||||||
extern edge_t *new_edge(void) __attribute__((__malloc__));
|
extern edge_t *new_edge(void) __attribute__((__malloc__));
|
||||||
extern void free_edge(edge_t *);
|
extern void free_edge(edge_t *e);
|
||||||
extern splay_tree_t *new_edge_tree(void) __attribute__((__malloc__));
|
extern splay_tree_t *new_edge_tree(void) __attribute__((__malloc__));
|
||||||
extern void free_edge_tree(splay_tree_t *);
|
extern void free_edge_tree(splay_tree_t *edge_tree);
|
||||||
extern void edge_add(edge_t *);
|
extern void edge_add(edge_t *e);
|
||||||
extern void edge_del(edge_t *);
|
extern void edge_del(edge_t *e);
|
||||||
extern edge_t *lookup_edge(struct node_t *, struct node_t *);
|
extern edge_t *lookup_edge(struct node_t *from, struct node_t *to);
|
||||||
extern bool dump_edges(struct connection_t *);
|
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
|
ethernet.h -- missing Ethernet related definitions
|
||||||
Copyright (C) 2005 Ivo Timmermans
|
Copyright (C) 2005 Ivo Timmermans
|
||||||
|
@ -18,9 +21,6 @@
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TINC_ETHERNET_H__
|
|
||||||
#define __TINC_ETHERNET_H__
|
|
||||||
|
|
||||||
#ifndef ETH_ALEN
|
#ifndef ETH_ALEN
|
||||||
#define ETH_ALEN 6
|
#define ETH_ALEN 6
|
||||||
#endif
|
#endif
|
||||||
|
@ -99,4 +99,4 @@ struct ether_arp {
|
||||||
#define arp_op ea_hdr.ar_op
|
#define arp_op ea_hdr.ar_op
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __TINC_ETHERNET_H__ */
|
#endif
|
||||||
|
|
253
src/event.c
253
src/event.c
|
@ -41,25 +41,47 @@ static int io_compare(const io_t *a, const io_t *b) {
|
||||||
#ifndef HAVE_MINGW
|
#ifndef HAVE_MINGW
|
||||||
return a->fd - b->fd;
|
return a->fd - b->fd;
|
||||||
#else
|
#else
|
||||||
return a->event - b->event;
|
|
||||||
|
if(a->event < b->event) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(a->event > b->event) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int timeout_compare(const timeout_t *a, const timeout_t *b) {
|
static int timeout_compare(const timeout_t *a, const timeout_t *b) {
|
||||||
struct timeval diff;
|
struct timeval diff;
|
||||||
timersub(&a->tv, &b->tv, &diff);
|
timersub(&a->tv, &b->tv, &diff);
|
||||||
if(diff.tv_sec < 0)
|
|
||||||
|
if(diff.tv_sec < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
if(diff.tv_sec > 0)
|
}
|
||||||
|
|
||||||
|
if(diff.tv_sec > 0) {
|
||||||
return 1;
|
return 1;
|
||||||
if(diff.tv_usec < 0)
|
}
|
||||||
|
|
||||||
|
if(diff.tv_usec < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
if(diff.tv_usec > 0)
|
}
|
||||||
|
|
||||||
|
if(diff.tv_usec > 0) {
|
||||||
return 1;
|
return 1;
|
||||||
if(a < b)
|
}
|
||||||
|
|
||||||
|
if(a < b) {
|
||||||
return -1;
|
return -1;
|
||||||
if(a > b)
|
}
|
||||||
|
|
||||||
|
if(a > b) {
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
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};
|
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) {
|
void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags) {
|
||||||
if(io->cb)
|
if(io->cb) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
io->fd = fd;
|
io->fd = fd;
|
||||||
#ifdef HAVE_MINGW
|
#ifdef HAVE_MINGW
|
||||||
|
|
||||||
if(io->fd != -1) {
|
if(io->fd != -1) {
|
||||||
io->event = WSACreateEvent();
|
io->event = WSACreateEvent();
|
||||||
if (io->event == WSA_INVALID_EVENT)
|
|
||||||
|
if(io->event == WSA_INVALID_EVENT) {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
event_count++;
|
event_count++;
|
||||||
#endif
|
#endif
|
||||||
io->cb = cb;
|
io->cb = cb;
|
||||||
|
@ -85,9 +112,10 @@ void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags) {
|
||||||
|
|
||||||
io_set(io, flags);
|
io_set(io, flags);
|
||||||
|
|
||||||
if(!splay_insert_node(&io_tree, &io->node))
|
if(!splay_insert_node(&io_tree, &io->node)) {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_MINGW
|
#ifdef HAVE_MINGW
|
||||||
void io_add_event(io_t *io, io_cb_t cb, void *data, WSAEVENT event) {
|
void io_add_event(io_t *io, io_cb_t cb, void *data, WSAEVENT event) {
|
||||||
|
@ -97,41 +125,60 @@ void io_add_event(io_t *io, io_cb_t cb, void *data, WSAEVENT event) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void io_set(io_t *io, int flags) {
|
void io_set(io_t *io, int flags) {
|
||||||
if (flags == io->flags)
|
if(flags == io->flags) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
io->flags = flags;
|
io->flags = flags;
|
||||||
if (io->fd == -1)
|
|
||||||
|
if(io->fd == -1) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef HAVE_MINGW
|
#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);
|
FD_SET(io->fd, &writefds);
|
||||||
else
|
} else {
|
||||||
FD_CLR(io->fd, &writefds);
|
FD_CLR(io->fd, &writefds);
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
long events = 0;
|
long events = 0;
|
||||||
if (flags & IO_WRITE)
|
|
||||||
|
if(flags & IO_WRITE) {
|
||||||
events |= WRITE_EVENTS;
|
events |= WRITE_EVENTS;
|
||||||
if (flags & IO_READ)
|
}
|
||||||
|
|
||||||
|
if(flags & IO_READ) {
|
||||||
events |= READ_EVENTS;
|
events |= READ_EVENTS;
|
||||||
if (WSAEventSelect(io->fd, io->event, events) != 0)
|
}
|
||||||
|
|
||||||
|
if(WSAEventSelect(io->fd, io->event, events) != 0) {
|
||||||
abort();
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void io_del(io_t *io) {
|
void io_del(io_t *io) {
|
||||||
if(!io->cb)
|
if(!io->cb) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
io_set(io, 0);
|
io_set(io, 0);
|
||||||
#ifdef HAVE_MINGW
|
#ifdef HAVE_MINGW
|
||||||
if (io->fd != -1 && WSACloseEvent(io->event) == FALSE)
|
|
||||||
|
if(io->fd != -1 && WSACloseEvent(io->event) == FALSE) {
|
||||||
abort();
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
event_count--;
|
event_count--;
|
||||||
#endif
|
#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) {
|
void timeout_set(timeout_t *timeout, struct timeval *tv) {
|
||||||
if(timerisset(&timeout->tv))
|
if(timerisset(&timeout->tv)) {
|
||||||
splay_unlink_node(&timeout_tree, &timeout->node);
|
splay_unlink_node(&timeout_tree, &timeout->node);
|
||||||
|
}
|
||||||
|
|
||||||
if(!now.tv_sec)
|
if(!now.tv_sec) {
|
||||||
gettimeofday(&now, NULL);
|
gettimeofday(&now, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
timeradd(&now, tv, &timeout->tv);
|
timeradd(&now, tv, &timeout->tv);
|
||||||
|
|
||||||
if(!splay_insert_node(&timeout_tree, &timeout->node))
|
if(!splay_insert_node(&timeout_tree, &timeout->node)) {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void timeout_del(timeout_t *timeout) {
|
void timeout_del(timeout_t *timeout) {
|
||||||
if(!timeout->cb)
|
if(!timeout->cb) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
splay_unlink_node(&timeout_tree, &timeout->node);
|
splay_unlink_node(&timeout_tree, &timeout->node);
|
||||||
timeout->cb = 0;
|
timeout->cb = 0;
|
||||||
timeout->tv = (struct timeval){0, 0};
|
timeout->tv = (struct timeval) {
|
||||||
|
0, 0
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef HAVE_MINGW
|
#ifndef HAVE_MINGW
|
||||||
|
@ -184,41 +237,54 @@ static void signal_handler(int signum) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void signalio_handler(void *data, int flags) {
|
static void signalio_handler(void *data, int flags) {
|
||||||
|
(void)data;
|
||||||
|
(void)flags;
|
||||||
unsigned char signum;
|
unsigned char signum;
|
||||||
if(read(pipefd[0], &signum, 1) != 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
signal_t *sig = splay_search(&signal_tree, &((signal_t){.signum = signum}));
|
if(read(pipefd[0], &signum, 1) != 1) {
|
||||||
if(sig)
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
signal_t *sig = splay_search(&signal_tree, &((signal_t) {
|
||||||
|
.signum = signum
|
||||||
|
}));
|
||||||
|
|
||||||
|
if(sig) {
|
||||||
sig->cb(sig->data);
|
sig->cb(sig->data);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void pipe_init(void) {
|
static void pipe_init(void) {
|
||||||
if(!pipe(pipefd))
|
if(!pipe(pipefd)) {
|
||||||
io_add(&signalio, signalio_handler, NULL, pipefd[0], IO_READ);
|
io_add(&signalio, signalio_handler, NULL, pipefd[0], IO_READ);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void signal_add(signal_t *sig, signal_cb_t cb, void *data, int signum) {
|
void signal_add(signal_t *sig, signal_cb_t cb, void *data, int signum) {
|
||||||
if(sig->cb)
|
if(sig->cb) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
sig->cb = cb;
|
sig->cb = cb;
|
||||||
sig->data = data;
|
sig->data = data;
|
||||||
sig->signum = signum;
|
sig->signum = signum;
|
||||||
sig->node.data = sig;
|
sig->node.data = sig;
|
||||||
|
|
||||||
if(pipefd[0] == -1)
|
if(pipefd[0] == -1) {
|
||||||
pipe_init();
|
pipe_init();
|
||||||
|
}
|
||||||
|
|
||||||
signal(sig->signum, signal_handler);
|
signal(sig->signum, signal_handler);
|
||||||
|
|
||||||
if(!splay_insert_node(&signal_tree, &sig->node))
|
if(!splay_insert_node(&signal_tree, &sig->node)) {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void signal_del(signal_t *sig) {
|
void signal_del(signal_t *sig) {
|
||||||
if(!sig->cb)
|
if(!sig->cb) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
signal(sig->signum, SIG_DFL);
|
signal(sig->signum, SIG_DFL);
|
||||||
|
|
||||||
|
@ -237,8 +303,10 @@ static struct timeval * get_time_remaining(struct timeval *diff) {
|
||||||
|
|
||||||
if(diff->tv_sec < 0) {
|
if(diff->tv_sec < 0) {
|
||||||
timeout->cb(timeout->data);
|
timeout->cb(timeout->data);
|
||||||
if(timercmp(&timeout->tv, &now, <))
|
|
||||||
|
if(timercmp(&timeout->tv, &now, <)) {
|
||||||
timeout_del(timeout);
|
timeout_del(timeout);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
tv = diff;
|
tv = diff;
|
||||||
break;
|
break;
|
||||||
|
@ -258,8 +326,8 @@ bool event_loop(void) {
|
||||||
while(running) {
|
while(running) {
|
||||||
struct timeval diff;
|
struct timeval diff;
|
||||||
struct timeval *tv = get_time_remaining(&diff);
|
struct timeval *tv = get_time_remaining(&diff);
|
||||||
memcpy(&readable, &readfds, sizeof readable);
|
memcpy(&readable, &readfds, sizeof(readable));
|
||||||
memcpy(&writable, &writefds, sizeof writable);
|
memcpy(&writable, &writefds, sizeof(writable));
|
||||||
|
|
||||||
int fds = 0;
|
int fds = 0;
|
||||||
|
|
||||||
|
@ -271,33 +339,42 @@ bool event_loop(void) {
|
||||||
int n = select(fds, &readable, &writable, NULL, tv);
|
int n = select(fds, &readable, &writable, NULL, tv);
|
||||||
|
|
||||||
if(n < 0) {
|
if(n < 0) {
|
||||||
if(sockwouldblock(sockerrno))
|
if(sockwouldblock(sockerrno)) {
|
||||||
continue;
|
continue;
|
||||||
else
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(!n)
|
if(!n) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int curgen = io_tree.generation;
|
||||||
|
|
||||||
for splay_each(io_t, io, &io_tree) {
|
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);
|
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);
|
io->cb(io->data, IO_READ);
|
||||||
else
|
} else {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
There are scenarios in which the callback will remove another io_t from the tree
|
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
|
(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
|
need to exit the loop if that happens. That's okay, since any remaining events will
|
||||||
up by the next select() call.
|
get picked up by the next select() call.
|
||||||
*/
|
*/
|
||||||
|
if(curgen != io_tree.generation) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
while(running) {
|
while(running) {
|
||||||
struct timeval diff;
|
struct timeval diff;
|
||||||
struct timeval *tv = get_time_remaining(&diff);
|
struct timeval *tv = get_time_remaining(&diff);
|
||||||
|
@ -318,54 +395,90 @@ bool event_loop(void) {
|
||||||
Note that technically FD_CLOSE has the same problem, but it's okay because user code does not rely on
|
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.
|
this event being fired again if ignored.
|
||||||
*/
|
*/
|
||||||
io_t* writeable_io = NULL;
|
unsigned int curgen = io_tree.generation;
|
||||||
for splay_each(io_t, io, &io_tree)
|
|
||||||
|
for splay_each(io_t, io, &io_tree) {
|
||||||
if(io->flags & IO_WRITE && send(io->fd, NULL, 0, 0) == 0) {
|
if(io->flags & IO_WRITE && send(io->fd, NULL, 0, 0) == 0) {
|
||||||
writeable_io = io;
|
io->cb(io->data, IO_WRITE);
|
||||||
|
|
||||||
|
if(curgen != io_tree.generation) {
|
||||||
break;
|
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;
|
DWORD event_index = 0;
|
||||||
|
|
||||||
for splay_each(io_t, io, &io_tree) {
|
for splay_each(io_t, io, &io_tree) {
|
||||||
events[event_index] = io->event;
|
events[event_index] = io->event;
|
||||||
|
io_map[event_index] = io;
|
||||||
event_index++;
|
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;
|
for(DWORD event_offset = 0; event_offset < event_count;) {
|
||||||
if (result >= WSA_WAIT_EVENT_0 && result < WSA_WAIT_EVENT_0 + event_count)
|
DWORD result = WSAWaitForMultipleEvents(event_count - event_offset, &events[event_offset], FALSE, timeout_ms, FALSE);
|
||||||
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;
|
|
||||||
|
|
||||||
io_t *io = splay_search(&io_tree, &((io_t){.event = event}));
|
if(result == WSA_WAIT_TIMEOUT) {
|
||||||
if (!io)
|
break;
|
||||||
abort();
|
}
|
||||||
|
|
||||||
|
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) {
|
if(io->fd == -1) {
|
||||||
io->cb(io->data, 0);
|
io->cb(io->data, 0);
|
||||||
|
|
||||||
|
if(curgen != io_tree.generation) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
WSANETWORKEVENTS network_events;
|
WSANETWORKEVENTS network_events;
|
||||||
if (WSAEnumNetworkEvents(io->fd, io->event, &network_events) != 0)
|
|
||||||
return false;
|
if(WSAEnumNetworkEvents(io->fd, io->event, &network_events) != 0) {
|
||||||
if (network_events.lNetworkEvents & READ_EVENTS)
|
return(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(network_events.lNetworkEvents & READ_EVENTS) {
|
||||||
io->cb(io->data, IO_READ);
|
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
|
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
|
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.
|
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
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
#ifndef TINC_EVENT_H
|
||||||
|
#define TINC_EVENT_H
|
||||||
|
|
||||||
/*
|
/*
|
||||||
event.h -- I/O, timeout and signal event handling
|
event.h -- I/O, timeout and signal event handling
|
||||||
Copyright (C) 2012-2013 Guus Sliepen <guus@tinc-vpn.org>
|
Copyright (C) 2012-2013 Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
@ -17,9 +20,6 @@
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TINC_EVENT_H__
|
|
||||||
#define __TINC_EVENT_H__
|
|
||||||
|
|
||||||
#include "splay_tree.h"
|
#include "splay_tree.h"
|
||||||
|
|
||||||
#define IO_READ 1
|
#define IO_READ 1
|
||||||
|
|
|
@ -85,12 +85,14 @@ static inline void set_etherheader(vpn_packet_t *packet, uint16_t ethertype) {
|
||||||
|
|
||||||
static bool read_packet(vpn_packet_t *packet) {
|
static bool read_packet(vpn_packet_t *packet) {
|
||||||
int lenin = read(device_fd, DATA(packet) + ETH_HLEN, MTU - ETH_HLEN);
|
int lenin = read(device_fd, DATA(packet) + ETH_HLEN, MTU - ETH_HLEN);
|
||||||
|
|
||||||
if(lenin <= 0) {
|
if(lenin <= 0) {
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from fd/%d: %s!", device_fd, strerror(errno));
|
logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from fd/%d: %s!", device_fd, strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ethertype = get_ip_ethertype(packet);
|
uint16_t ethertype = get_ip_ethertype(packet);
|
||||||
|
|
||||||
if(ethertype == ETH_P_MAX) {
|
if(ethertype == ETH_P_MAX) {
|
||||||
logger(DEBUG_TRAFFIC, LOG_ERR, "Unknown IP version while reading packet from fd/%d!", device_fd);
|
logger(DEBUG_TRAFFIC, LOG_ERR, "Unknown IP version while reading packet from fd/%d!", device_fd);
|
||||||
return false;
|
return false;
|
||||||
|
|
216
src/fsck.c
216
src/fsck.c
|
@ -32,31 +32,43 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
static bool ask_fix(void) {
|
static bool ask_fix(void) {
|
||||||
if(force)
|
if(force) {
|
||||||
return true;
|
return true;
|
||||||
if(!tty)
|
}
|
||||||
|
|
||||||
|
if(!tty) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
again:
|
again:
|
||||||
fprintf(stderr, "Fix y/n? ");
|
fprintf(stderr, "Fix y/n? ");
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
if(!fgets(buf, sizeof buf, stdin)) {
|
|
||||||
|
if(!fgets(buf, sizeof(buf), stdin)) {
|
||||||
tty = false;
|
tty = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(buf[0] == 'y' || buf[0] == 'Y')
|
|
||||||
|
if(buf[0] == 'y' || buf[0] == 'Y') {
|
||||||
return true;
|
return true;
|
||||||
if(buf[0] == 'n' || buf[0] == 'N')
|
}
|
||||||
|
|
||||||
|
if(buf[0] == 'n' || buf[0] == 'N') {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_tinc_cmd(const char *argv0, const char *format, ...) {
|
static void print_tinc_cmd(const char *argv0, const char *format, ...) {
|
||||||
if(confbasegiven)
|
if(confbasegiven) {
|
||||||
fprintf(stderr, "%s -c %s ", argv0, confbase);
|
fprintf(stderr, "%s -c %s ", argv0, confbase);
|
||||||
else if(netname)
|
} else if(netname) {
|
||||||
fprintf(stderr, "%s -n %s ", argv0, netname);
|
fprintf(stderr, "%s -n %s ", argv0, netname);
|
||||||
else
|
} else {
|
||||||
fprintf(stderr, "%s ", argv0);
|
fprintf(stderr, "%s ", argv0);
|
||||||
|
}
|
||||||
|
|
||||||
va_list va;
|
va_list va;
|
||||||
va_start(va, format);
|
va_start(va, format);
|
||||||
vfprintf(stderr, format, va);
|
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) {
|
static int strtailcmp(const char *str, const char *tail) {
|
||||||
size_t slen = strlen(str);
|
size_t slen = strlen(str);
|
||||||
size_t tlen = strlen(tail);
|
size_t tlen = strlen(tail);
|
||||||
if(tlen > slen)
|
|
||||||
|
if(tlen > slen) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return memcmp(str + slen - tlen, tail, tlen);
|
return memcmp(str + slen - tlen, tail, tlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void check_conffile(const char *fname, bool server) {
|
static void check_conffile(const char *fname, bool server) {
|
||||||
|
(void)server;
|
||||||
|
|
||||||
FILE *f = fopen(fname, "r");
|
FILE *f = fopen(fname, "r");
|
||||||
|
|
||||||
if(!f) {
|
if(!f) {
|
||||||
fprintf(stderr, "ERROR: cannot read %s: %s\n", fname, strerror(errno));
|
fprintf(stderr, "ERROR: cannot read %s: %s\n", fname, strerror(errno));
|
||||||
return;
|
return;
|
||||||
|
@ -84,12 +102,14 @@ static void check_conffile(const char *fname, bool server) {
|
||||||
bool skip = false;
|
bool skip = false;
|
||||||
const int maxvariables = 50;
|
const int maxvariables = 50;
|
||||||
int count[maxvariables];
|
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(skip) {
|
||||||
if(!strncmp(line, "-----END", 8))
|
if(!strncmp(line, "-----END", 8)) {
|
||||||
skip = false;
|
skip = false;
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
if(!strncmp(line, "-----BEGIN", 10)) {
|
if(!strncmp(line, "-----BEGIN", 10)) {
|
||||||
|
@ -105,26 +125,32 @@ static void check_conffile(const char *fname, bool server) {
|
||||||
lineno++;
|
lineno++;
|
||||||
|
|
||||||
eol = line + strlen(line);
|
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;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
len = strcspn(value, "\t =");
|
len = strcspn(value, "\t =");
|
||||||
value += len;
|
value += len;
|
||||||
value += strspn(value, "\t ");
|
value += strspn(value, "\t ");
|
||||||
|
|
||||||
if(*value == '=') {
|
if(*value == '=') {
|
||||||
value++;
|
value++;
|
||||||
value += strspn(value, "\t ");
|
value += strspn(value, "\t ");
|
||||||
}
|
}
|
||||||
|
|
||||||
variable[len] = '\0';
|
variable[len] = '\0';
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
for(int i = 0; variables[i].name; i++) {
|
for(int i = 0; variables[i].name; i++) {
|
||||||
if(strcasecmp(variables[i].name, variable))
|
if(strcasecmp(variables[i].name, variable)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
found = true;
|
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);
|
fprintf(stderr, "WARNING: obsolete variable %s in %s line %d\n", variable, fname, lineno);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(i < maxvariables)
|
if(i < maxvariables) {
|
||||||
count[i]++;
|
count[i]++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(!found)
|
if(!found) {
|
||||||
fprintf(stderr, "WARNING: unknown variable %s in %s line %d\n", variable, fname, lineno);
|
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);
|
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++) {
|
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);
|
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));
|
fprintf(stderr, "ERROR: while reading %s: %s\n", fname, strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
@ -165,19 +196,23 @@ int fsck(const char *argv0) {
|
||||||
|
|
||||||
if(access(tinc_conf, R_OK)) {
|
if(access(tinc_conf, R_OK)) {
|
||||||
fprintf(stderr, "ERROR: cannot read %s: %s\n", tinc_conf, strerror(errno));
|
fprintf(stderr, "ERROR: cannot read %s: %s\n", tinc_conf, strerror(errno));
|
||||||
|
|
||||||
if(errno == ENOENT) {
|
if(errno == ENOENT) {
|
||||||
fprintf(stderr, "No tinc configuration found. Create a new one with:\n\n");
|
fprintf(stderr, "No tinc configuration found. Create a new one with:\n\n");
|
||||||
print_tinc_cmd(argv0, "init");
|
print_tinc_cmd(argv0, "init");
|
||||||
} else if(errno == EACCES) {
|
} else if(errno == EACCES) {
|
||||||
if(uid != 0)
|
if(uid != 0) {
|
||||||
fprintf(stderr, "You are currently not running tinc as root. Use sudo?\n");
|
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);
|
fprintf(stderr, "Check the permissions of each component of the path %s.\n", tinc_conf);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *name = get_my_name(true);
|
char *name = get_my_name(true);
|
||||||
|
|
||||||
if(!name) {
|
if(!name) {
|
||||||
fprintf(stderr, "ERROR: tinc cannot run without a valid Name.\n");
|
fprintf(stderr, "ERROR: tinc cannot run without a valid Name.\n");
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -192,7 +227,7 @@ int fsck(const char *argv0) {
|
||||||
|
|
||||||
#ifndef DISABLE_LEGACY
|
#ifndef DISABLE_LEGACY
|
||||||
rsa_t *rsa_priv = NULL;
|
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(stat(fname, &st)) {
|
||||||
if(errno != ENOENT) {
|
if(errno != ENOENT) {
|
||||||
|
@ -203,12 +238,15 @@ int fsck(const char *argv0) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
FILE *f = fopen(fname, "r");
|
FILE *f = fopen(fname, "r");
|
||||||
|
|
||||||
if(!f) {
|
if(!f) {
|
||||||
fprintf(stderr, "ERROR: could not open %s: %s\n", fname, strerror(errno));
|
fprintf(stderr, "ERROR: could not open %s: %s\n", fname, strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
rsa_priv = rsa_read_pem_private_key(f);
|
rsa_priv = rsa_read_pem_private_key(f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
if(!rsa_priv) {
|
if(!rsa_priv) {
|
||||||
fprintf(stderr, "ERROR: No key or unusable key found in %s.\n", fname);
|
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");
|
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 !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN)
|
||||||
|
|
||||||
if(st.st_mode & 077) {
|
if(st.st_mode & 077) {
|
||||||
fprintf(stderr, "WARNING: unsafe file permissions on %s.\n", fname);
|
fprintf(stderr, "WARNING: unsafe file permissions on %s.\n", fname);
|
||||||
|
|
||||||
if(st.st_uid != uid) {
|
if(st.st_uid != uid) {
|
||||||
fprintf(stderr, "You are not running %s as the same uid as %s.\n", argv0, fname);
|
fprintf(stderr, "You are not running %s as the same uid as %s.\n", argv0, fname);
|
||||||
} else if(ask_fix()) {
|
} 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));
|
fprintf(stderr, "ERROR: could not change permissions of %s: %s\n", fname, strerror(errno));
|
||||||
else
|
} else {
|
||||||
fprintf(stderr, "Fixed permissions of %s.\n", fname);
|
fprintf(stderr, "Fixed permissions of %s.\n", fname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ecdsa_t *ecdsa_priv = NULL;
|
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(stat(fname, &st)) {
|
||||||
if(errno != ENOENT) {
|
if(errno != ENOENT) {
|
||||||
|
@ -244,12 +287,15 @@ int fsck(const char *argv0) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
FILE *f = fopen(fname, "r");
|
FILE *f = fopen(fname, "r");
|
||||||
|
|
||||||
if(!f) {
|
if(!f) {
|
||||||
fprintf(stderr, "ERROR: could not open %s: %s\n", fname, strerror(errno));
|
fprintf(stderr, "ERROR: could not open %s: %s\n", fname, strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ecdsa_priv = ecdsa_read_pem_private_key(f);
|
ecdsa_priv = ecdsa_read_pem_private_key(f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
if(!ecdsa_priv) {
|
if(!ecdsa_priv) {
|
||||||
fprintf(stderr, "ERROR: No key or unusable key found in %s.\n", fname);
|
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");
|
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 !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN)
|
||||||
|
|
||||||
if(st.st_mode & 077) {
|
if(st.st_mode & 077) {
|
||||||
fprintf(stderr, "WARNING: unsafe file permissions on %s.\n", fname);
|
fprintf(stderr, "WARNING: unsafe file permissions on %s.\n", fname);
|
||||||
|
|
||||||
if(st.st_uid != uid) {
|
if(st.st_uid != uid) {
|
||||||
fprintf(stderr, "You are not running %s as the same uid as %s.\n", argv0, fname);
|
fprintf(stderr, "You are not running %s as the same uid as %s.\n", argv0, fname);
|
||||||
} else if(ask_fix()) {
|
} 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));
|
fprintf(stderr, "ERROR: could not change permissions of %s: %s\n", fname, strerror(errno));
|
||||||
else
|
} else {
|
||||||
fprintf(stderr, "Fixed permissions of %s.\n", fname);
|
fprintf(stderr, "Fixed permissions of %s.\n", fname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DISABLE_LEGACY
|
#ifdef DISABLE_LEGACY
|
||||||
|
|
||||||
if(!ecdsa_priv) {
|
if(!ecdsa_priv) {
|
||||||
fprintf(stderr, "ERROR: No Ed25519 private key found.\n");
|
fprintf(stderr, "ERROR: No Ed25519 private key found.\n");
|
||||||
#else
|
#else
|
||||||
|
|
||||||
if(!rsa_priv && !ecdsa_priv) {
|
if(!rsa_priv && !ecdsa_priv) {
|
||||||
fprintf(stderr, "ERROR: Neither RSA or Ed25519 private key found.\n");
|
fprintf(stderr, "ERROR: Neither RSA or Ed25519 private key found.\n");
|
||||||
#endif
|
#endif
|
||||||
|
@ -287,9 +339,11 @@ int fsck(const char *argv0) {
|
||||||
// Check for public keys.
|
// Check for public keys.
|
||||||
// TODO: use RSAPublicKeyFile variable if present.
|
// TODO: use RSAPublicKeyFile variable if present.
|
||||||
|
|
||||||
snprintf(fname, sizeof fname, "%s/hosts/%s", confbase, name);
|
snprintf(fname, sizeof(fname), "%s/hosts/%s", confbase, name);
|
||||||
if(access(fname, R_OK))
|
|
||||||
|
if(access(fname, R_OK)) {
|
||||||
fprintf(stderr, "WARNING: cannot read %s\n", fname);
|
fprintf(stderr, "WARNING: cannot read %s\n", fname);
|
||||||
|
}
|
||||||
|
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
|
||||||
|
@ -297,6 +351,7 @@ int fsck(const char *argv0) {
|
||||||
rsa_t *rsa_pub = NULL;
|
rsa_t *rsa_pub = NULL;
|
||||||
|
|
||||||
f = fopen(fname, "r");
|
f = fopen(fname, "r");
|
||||||
|
|
||||||
if(f) {
|
if(f) {
|
||||||
rsa_pub = rsa_read_pem_public_key(f);
|
rsa_pub = rsa_read_pem_public_key(f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
@ -305,13 +360,17 @@ int fsck(const char *argv0) {
|
||||||
if(rsa_priv) {
|
if(rsa_priv) {
|
||||||
if(!rsa_pub) {
|
if(!rsa_pub) {
|
||||||
fprintf(stderr, "WARNING: No (usable) public RSA key found.\n");
|
fprintf(stderr, "WARNING: No (usable) public RSA key found.\n");
|
||||||
|
|
||||||
if(ask_fix()) {
|
if(ask_fix()) {
|
||||||
FILE *f = fopen(fname, "a");
|
FILE *f = fopen(fname, "a");
|
||||||
|
|
||||||
if(f) {
|
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);
|
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);
|
fprintf(stderr, "ERROR: could not write RSA public key to %s.\n", fname);
|
||||||
|
}
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "ERROR: could not append to %s: %s\n", fname, strerror(errno));
|
fprintf(stderr, "ERROR: could not append to %s: %s\n", fname, strerror(errno));
|
||||||
|
@ -320,56 +379,70 @@ int fsck(const char *argv0) {
|
||||||
} else {
|
} else {
|
||||||
// TODO: suggest remedies
|
// TODO: suggest remedies
|
||||||
size_t len = rsa_size(rsa_priv);
|
size_t len = rsa_size(rsa_priv);
|
||||||
|
|
||||||
if(len != rsa_size(rsa_pub)) {
|
if(len != rsa_size(rsa_pub)) {
|
||||||
fprintf(stderr, "ERROR: public and private RSA keys do not match.\n");
|
fprintf(stderr, "ERROR: public and private RSA keys do not match.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
char buf1[len], buf2[len], buf3[len];
|
char buf1[len], buf2[len], buf3[len];
|
||||||
randomize(buf1, sizeof buf1);
|
randomize(buf1, sizeof(buf1));
|
||||||
buf1[0] &= 0x7f;
|
buf1[0] &= 0x7f;
|
||||||
memset(buf2, 0, sizeof buf2);
|
memset(buf2, 0, sizeof(buf2));
|
||||||
memset(buf3, 0, sizeof buf2);
|
memset(buf3, 0, sizeof(buf2));
|
||||||
if(!rsa_public_encrypt(rsa_pub, buf1, sizeof buf1, buf2)) {
|
|
||||||
|
if(!rsa_public_encrypt(rsa_pub, buf1, sizeof(buf1), buf2)) {
|
||||||
fprintf(stderr, "ERROR: public RSA key does not work.\n");
|
fprintf(stderr, "ERROR: public RSA key does not work.\n");
|
||||||
return 1;
|
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");
|
fprintf(stderr, "ERROR: private RSA key does not work.\n");
|
||||||
return 1;
|
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");
|
fprintf(stderr, "ERROR: public and private RSA keys do not match.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(rsa_pub)
|
if(rsa_pub) {
|
||||||
fprintf(stderr, "WARNING: A public RSA key was found but no private key is known.\n");
|
fprintf(stderr, "WARNING: A public RSA key was found but no private key is known.\n");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ecdsa_t *ecdsa_pub = NULL;
|
ecdsa_t *ecdsa_pub = NULL;
|
||||||
|
|
||||||
f = fopen(fname, "r");
|
f = fopen(fname, "r");
|
||||||
|
|
||||||
if(f) {
|
if(f) {
|
||||||
ecdsa_pub = get_pubkey(f);
|
ecdsa_pub = get_pubkey(f);
|
||||||
|
|
||||||
if(!ecdsa_pub) {
|
if(!ecdsa_pub) {
|
||||||
rewind(f);
|
rewind(f);
|
||||||
ecdsa_pub = ecdsa_read_pem_public_key(f);
|
ecdsa_pub = ecdsa_read_pem_public_key(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ecdsa_priv) {
|
if(ecdsa_priv) {
|
||||||
if(!ecdsa_pub) {
|
if(!ecdsa_pub) {
|
||||||
fprintf(stderr, "WARNING: No (usable) public Ed25519 key found.\n");
|
fprintf(stderr, "WARNING: No (usable) public Ed25519 key found.\n");
|
||||||
|
|
||||||
if(ask_fix()) {
|
if(ask_fix()) {
|
||||||
FILE *f = fopen(fname, "a");
|
FILE *f = fopen(fname, "a");
|
||||||
|
|
||||||
if(f) {
|
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);
|
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);
|
fprintf(stderr, "ERROR: could not write Ed25519 public key to %s.\n", fname);
|
||||||
|
}
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "ERROR: could not append to %s: %s\n", fname, strerror(errno));
|
fprintf(stderr, "ERROR: could not append to %s: %s\n", fname, strerror(errno));
|
||||||
|
@ -378,104 +451,132 @@ int fsck(const char *argv0) {
|
||||||
} else {
|
} else {
|
||||||
// TODO: suggest remedies
|
// TODO: suggest remedies
|
||||||
char *key1 = ecdsa_get_base64_public_key(ecdsa_pub);
|
char *key1 = ecdsa_get_base64_public_key(ecdsa_pub);
|
||||||
|
|
||||||
if(!key1) {
|
if(!key1) {
|
||||||
fprintf(stderr, "ERROR: public Ed25519 key does not work.\n");
|
fprintf(stderr, "ERROR: public Ed25519 key does not work.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *key2 = ecdsa_get_base64_public_key(ecdsa_priv);
|
char *key2 = ecdsa_get_base64_public_key(ecdsa_priv);
|
||||||
|
|
||||||
if(!key2) {
|
if(!key2) {
|
||||||
free(key1);
|
free(key1);
|
||||||
fprintf(stderr, "ERROR: private Ed25519 key does not work.\n");
|
fprintf(stderr, "ERROR: private Ed25519 key does not work.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int result = strcmp(key1, key2);
|
int result = strcmp(key1, key2);
|
||||||
free(key1);
|
free(key1);
|
||||||
free(key2);
|
free(key2);
|
||||||
|
|
||||||
if(result) {
|
if(result) {
|
||||||
fprintf(stderr, "ERROR: public and private Ed25519 keys do not match.\n");
|
fprintf(stderr, "ERROR: public and private Ed25519 keys do not match.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(ecdsa_pub)
|
if(ecdsa_pub) {
|
||||||
fprintf(stderr, "WARNING: A public Ed25519 key was found but no private key is known.\n");
|
fprintf(stderr, "WARNING: A public Ed25519 key was found but no private key is known.\n");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check whether scripts are executable
|
// Check whether scripts are executable
|
||||||
|
|
||||||
struct dirent *ent;
|
struct dirent *ent;
|
||||||
DIR *dir = opendir(confbase);
|
DIR *dir = opendir(confbase);
|
||||||
|
|
||||||
if(!dir) {
|
if(!dir) {
|
||||||
fprintf(stderr, "ERROR: cannot read directory %s: %s\n", confbase, strerror(errno));
|
fprintf(stderr, "ERROR: cannot read directory %s: %s\n", confbase, strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while((ent = readdir(dir))) {
|
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;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
strncpy(fname, ent->d_name, sizeof fname);
|
strncpy(fname, ent->d_name, sizeof(fname));
|
||||||
char *dash = strrchr(fname, '-');
|
char *dash = strrchr(fname, '-');
|
||||||
if(!dash)
|
|
||||||
|
if(!dash) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
*dash = 0;
|
*dash = 0;
|
||||||
|
|
||||||
if(strcmp(fname, "tinc") && strcmp(fname, "host") && strcmp(fname, "subnet")) {
|
if(strcmp(fname, "tinc") && strcmp(fname, "host") && strcmp(fname, "subnet")) {
|
||||||
static bool explained = false;
|
static bool explained = false;
|
||||||
fprintf(stderr, "WARNING: Unknown script %s" SLASH "%s found.\n", confbase, ent->d_name);
|
fprintf(stderr, "WARNING: Unknown script %s" SLASH "%s found.\n", confbase, ent->d_name);
|
||||||
|
|
||||||
if(!explained) {
|
if(!explained) {
|
||||||
fprintf(stderr, "The only scripts in %s executed by tinc are:\n", confbase);
|
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");
|
fprintf(stderr, "tinc-up, tinc-down, host-up, host-down, subnet-up and subnet-down.\n");
|
||||||
explained = true;
|
explained = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
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(access(fname, R_OK | X_OK)) {
|
||||||
if(errno != EACCES) {
|
if(errno != EACCES) {
|
||||||
fprintf(stderr, "ERROR: cannot access %s: %s\n", fname, strerror(errno));
|
fprintf(stderr, "ERROR: cannot access %s: %s\n", fname, strerror(errno));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "WARNING: cannot read and execute %s: %s\n", fname, strerror(errno));
|
fprintf(stderr, "WARNING: cannot read and execute %s: %s\n", fname, strerror(errno));
|
||||||
|
|
||||||
if(ask_fix()) {
|
if(ask_fix()) {
|
||||||
if(chmod(fname, 0755))
|
if(chmod(fname, 0755)) {
|
||||||
fprintf(stderr, "ERROR: cannot change permissions on %s: %s\n", fname, strerror(errno));
|
fprintf(stderr, "ERROR: cannot change permissions on %s: %s\n", fname, strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
|
|
||||||
snprintf(dname, sizeof dname, "%s" SLASH "hosts", confbase);
|
snprintf(dname, sizeof(dname), "%s" SLASH "hosts", confbase);
|
||||||
dir = opendir(dname);
|
dir = opendir(dname);
|
||||||
|
|
||||||
if(!dir) {
|
if(!dir) {
|
||||||
fprintf(stderr, "ERROR: cannot read directory %s: %s\n", dname, strerror(errno));
|
fprintf(stderr, "ERROR: cannot read directory %s: %s\n", dname, strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while((ent = readdir(dir))) {
|
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;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
strncpy(fname, ent->d_name, sizeof fname);
|
strncpy(fname, ent->d_name, sizeof(fname));
|
||||||
char *dash = strrchr(fname, '-');
|
char *dash = strrchr(fname, '-');
|
||||||
if(!dash)
|
|
||||||
|
if(!dash) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
*dash = 0;
|
*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(access(fname, R_OK | X_OK)) {
|
||||||
if(errno != EACCES) {
|
if(errno != EACCES) {
|
||||||
fprintf(stderr, "ERROR: cannot access %s: %s\n", fname, strerror(errno));
|
fprintf(stderr, "ERROR: cannot access %s: %s\n", fname, strerror(errno));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "WARNING: cannot read and execute %s: %s\n", fname, strerror(errno));
|
fprintf(stderr, "WARNING: cannot read and execute %s: %s\n", fname, strerror(errno));
|
||||||
|
|
||||||
if(ask_fix()) {
|
if(ask_fix()) {
|
||||||
if(chmod(fname, 0755))
|
if(chmod(fname, 0755)) {
|
||||||
fprintf(stderr, "ERROR: cannot change permissions on %s: %s\n", fname, strerror(errno));
|
fprintf(stderr, "ERROR: cannot change permissions on %s: %s\n", fname, strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
|
|
||||||
// Check for obsolete / unsafe / unknown configuration variables.
|
// Check for obsolete / unsafe / unknown configuration variables.
|
||||||
|
@ -483,14 +584,17 @@ int fsck(const char *argv0) {
|
||||||
check_conffile(tinc_conf, true);
|
check_conffile(tinc_conf, true);
|
||||||
|
|
||||||
dir = opendir(dname);
|
dir = opendir(dname);
|
||||||
|
|
||||||
if(dir) {
|
if(dir) {
|
||||||
while((ent = readdir(dir))) {
|
while((ent = readdir(dir))) {
|
||||||
if(!check_id(ent->d_name))
|
if(!check_id(ent->d_name)) {
|
||||||
continue;
|
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);
|
check_conffile(fname, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
#ifndef TINC_FSCK_H
|
||||||
|
#define TINC_FSCK_H
|
||||||
|
|
||||||
/*
|
/*
|
||||||
fsck.h -- header for fsck.c.
|
fsck.h -- header for fsck.c.
|
||||||
Copyright (C) 2012 Guus Sliepen <guus@tinc-vpn.org>
|
Copyright (C) 2012 Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
@ -17,10 +20,6 @@
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TINC_FSCK_H__
|
|
||||||
#define __TINC_FSCK_H__
|
|
||||||
|
|
||||||
extern int fsck(const char *argv0);
|
extern int fsck(const char *argv0);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ static struct {
|
||||||
static bool nametocipher(const char *name, int *algo, int *mode) {
|
static bool nametocipher(const char *name, int *algo, int *mode) {
|
||||||
size_t i;
|
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)) {
|
if(ciphertable[i].name && !strcasecmp(name, ciphertable[i].name)) {
|
||||||
*algo = ciphertable[i].algo;
|
*algo = ciphertable[i].algo;
|
||||||
*mode = ciphertable[i].mode;
|
*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) {
|
static bool nidtocipher(int nid, int *algo, int *mode) {
|
||||||
size_t i;
|
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) {
|
if(nid == ciphertable[i].nid) {
|
||||||
*algo = ciphertable[i].algo;
|
*algo = ciphertable[i].algo;
|
||||||
*mode = ciphertable[i].mode;
|
*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) {
|
static bool ciphertonid(int algo, int mode, int *nid) {
|
||||||
size_t i;
|
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) {
|
if(algo == ciphertable[i].algo && mode == ciphertable[i].mode) {
|
||||||
*nid = ciphertable[i].nid;
|
*nid = ciphertable[i].nid;
|
||||||
return true;
|
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))) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,11 +146,9 @@ void cipher_close(cipher_t *cipher) {
|
||||||
cipher->handle = NULL;
|
cipher->handle = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cipher->key) {
|
|
||||||
free(cipher->key);
|
free(cipher->key);
|
||||||
cipher->key = NULL;
|
cipher->key = NULL;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
size_t cipher_keylength(const cipher_t *cipher) {
|
size_t cipher_keylength(const cipher_t *cipher) {
|
||||||
return cipher->keylen + cipher->blklen;
|
return cipher->keylen + cipher->blklen;
|
||||||
|
@ -193,8 +191,9 @@ bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou
|
||||||
uint8_t pad[cipher->blklen];
|
uint8_t pad[cipher->blklen];
|
||||||
|
|
||||||
if(cipher->padding) {
|
if(cipher->padding) {
|
||||||
if(!oneshot)
|
if(!oneshot) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
size_t reqlen = ((inlen + cipher->blklen) / cipher->blklen) * cipher->blklen;
|
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;
|
inlen = reqlen - cipher->blklen;
|
||||||
|
|
||||||
for(int i = 0; i < cipher->blklen; i++)
|
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];
|
pad[i] = ((uint8_t *)indata)[inlen + i];
|
||||||
else
|
} else {
|
||||||
pad[i] = padbyte;
|
pad[i] = padbyte;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(oneshot)
|
if(oneshot) {
|
||||||
gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen);
|
gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen);
|
||||||
|
}
|
||||||
|
|
||||||
if((err = gcry_cipher_encrypt(cipher->handle, outdata, *outlen, indata, inlen))) {
|
if((err = gcry_cipher_encrypt(cipher->handle, outdata, *outlen, indata, inlen))) {
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: %s", gcry_strerror(err));
|
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) {
|
bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) {
|
||||||
gcry_error_t err;
|
gcry_error_t err;
|
||||||
|
|
||||||
if(oneshot)
|
if(oneshot) {
|
||||||
gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen);
|
gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen);
|
||||||
|
}
|
||||||
|
|
||||||
if((err = gcry_cipher_decrypt(cipher->handle, outdata, *outlen, indata, inlen))) {
|
if((err = gcry_cipher_decrypt(cipher->handle, outdata, *outlen, indata, inlen))) {
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting: %s", gcry_strerror(err));
|
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(cipher->padding) {
|
||||||
if(!oneshot)
|
if(!oneshot) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t padbyte = ((uint8_t *)outdata)[inlen - 1];
|
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;
|
*outlen = origlen;
|
||||||
} else
|
} else {
|
||||||
*outlen = inlen;
|
*outlen = inlen;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ static struct {
|
||||||
static bool nametodigest(const char *name, int *algo) {
|
static bool nametodigest(const char *name, int *algo) {
|
||||||
int i;
|
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)) {
|
if(digesttable[i].name && !strcasecmp(name, digesttable[i].name)) {
|
||||||
*algo = digesttable[i].algo;
|
*algo = digesttable[i].algo;
|
||||||
return true;
|
return true;
|
||||||
|
@ -50,7 +50,7 @@ static bool nametodigest(const char *name, int *algo) {
|
||||||
static bool nidtodigest(int nid, int *algo) {
|
static bool nidtodigest(int nid, int *algo) {
|
||||||
int i;
|
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) {
|
if(nid == digesttable[i].nid) {
|
||||||
*algo = digesttable[i].algo;
|
*algo = digesttable[i].algo;
|
||||||
return true;
|
return true;
|
||||||
|
@ -63,7 +63,7 @@ static bool nidtodigest(int nid, int *algo) {
|
||||||
static bool digesttonid(int algo, int *nid) {
|
static bool digesttonid(int algo, int *nid) {
|
||||||
int i;
|
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) {
|
if(algo == digesttable[i].algo) {
|
||||||
*nid = digesttable[i].nid;
|
*nid = digesttable[i].nid;
|
||||||
return true;
|
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);
|
unsigned int len = gcry_md_get_algo_dlen(algo);
|
||||||
|
|
||||||
if(maclength > len || maclength < 0)
|
if(maclength > len || maclength < 0) {
|
||||||
digest->maclength = len;
|
digest->maclength = len;
|
||||||
else
|
} else {
|
||||||
digest->maclength = maclength;
|
digest->maclength = maclength;
|
||||||
|
}
|
||||||
|
|
||||||
digest->algo = algo;
|
digest->algo = algo;
|
||||||
digest->hmac = NULL;
|
digest->hmac = NULL;
|
||||||
|
@ -119,16 +120,21 @@ bool digest_open_sha1(digest_t *digest, int maclength) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void digest_close(digest_t *digest) {
|
void digest_close(digest_t *digest) {
|
||||||
if(digest->hmac)
|
if(digest->hmac) {
|
||||||
gcry_md_close(digest->hmac);
|
gcry_md_close(digest->hmac);
|
||||||
|
}
|
||||||
|
|
||||||
digest->hmac = NULL;
|
digest->hmac = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool digest_set_key(digest_t *digest, const void *key, size_t len) {
|
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);
|
gcry_md_open(&digest->hmac, digest->algo, GCRY_MD_FLAG_HMAC);
|
||||||
if(!digest->hmac)
|
}
|
||||||
|
|
||||||
|
if(!digest->hmac) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return !gcry_md_setkey(digest->hmac, key, len);
|
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_reset(digest->hmac);
|
||||||
gcry_md_write(digest->hmac, indata, inlen);
|
gcry_md_write(digest->hmac, indata, inlen);
|
||||||
tmpdata = gcry_md_read(digest->hmac, digest->algo);
|
tmpdata = gcry_md_read(digest->hmac, digest->algo);
|
||||||
if(!tmpdata)
|
|
||||||
|
if(!tmpdata) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(outdata, tmpdata, digest->maclength);
|
memcpy(outdata, tmpdata, digest->maclength);
|
||||||
} else {
|
} else {
|
||||||
char tmpdata[len];
|
char tmpdata[len];
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
#ifndef TINC_GCRYPT_DIGEST_H
|
||||||
|
#define TINC_GCRYPT_DIGEST_H
|
||||||
|
|
||||||
/*
|
/*
|
||||||
digest.h -- header file digest.c
|
digest.h -- header file digest.c
|
||||||
Copyright (C) 2007-2009 Guus Sliepen <guus@tinc-vpn.org>
|
Copyright (C) 2007-2009 Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
@ -17,9 +20,6 @@
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TINC_DIGEST_H__
|
|
||||||
#define __TINC_DIGEST_H__
|
|
||||||
|
|
||||||
#include <gcrypt.h>
|
#include <gcrypt.h>
|
||||||
|
|
||||||
#define DIGEST_MAX_SIZE 64
|
#define DIGEST_MAX_SIZE 64
|
||||||
|
|
|
@ -23,9 +23,10 @@
|
||||||
#include "../ed25519/sha512.h"
|
#include "../ed25519/sha512.h"
|
||||||
|
|
||||||
static void memxor(char *buf, char c, size_t len) {
|
static void memxor(char *buf, char c, size_t len) {
|
||||||
for(size_t i = 0; i < len; i++)
|
for(size_t i = 0; i < len; i++) {
|
||||||
buf[i] ^= c;
|
buf[i] ^= c;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const size_t mdlen = 64;
|
static const size_t mdlen = 64;
|
||||||
static const size_t blklen = 128;
|
static const size_t blklen = 128;
|
||||||
|
@ -38,30 +39,39 @@ static bool hmac_sha512(const char *key, size_t keylen, const char *msg, size_t
|
||||||
memcpy(tmp, key, keylen);
|
memcpy(tmp, key, keylen);
|
||||||
memset(tmp + keylen, 0, blklen - keylen);
|
memset(tmp + keylen, 0, blklen - keylen);
|
||||||
} else {
|
} else {
|
||||||
if(sha512(key, keylen, tmp) != 0)
|
if(sha512(key, keylen, tmp) != 0) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
memset(tmp + mdlen, 0, blklen - mdlen);
|
memset(tmp + mdlen, 0, blklen - mdlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sha512_init(&md) != 0)
|
if(sha512_init(&md) != 0) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// ipad
|
// ipad
|
||||||
memxor(tmp, 0x36, blklen);
|
memxor(tmp, 0x36, blklen);
|
||||||
if(sha512_update(&md, tmp, blklen) != 0)
|
|
||||||
|
if(sha512_update(&md, tmp, blklen) != 0) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// message
|
// message
|
||||||
if(sha512_update(&md, msg, msglen) != 0)
|
if(sha512_update(&md, msg, msglen) != 0) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if(sha512_final(&md, tmp + blklen) != 0)
|
if(sha512_final(&md, tmp + blklen) != 0) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// opad
|
// opad
|
||||||
memxor(tmp, 0x36 ^ 0x5c, blklen);
|
memxor(tmp, 0x36 ^ 0x5c, blklen);
|
||||||
if(sha512(tmp, sizeof tmp, out) != 0)
|
|
||||||
|
if(sha512(tmp, sizeof(tmp), out) != 0) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -84,18 +94,23 @@ bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char
|
||||||
|
|
||||||
while(outlen > 0) {
|
while(outlen > 0) {
|
||||||
/* Inner HMAC */
|
/* Inner HMAC */
|
||||||
if(!hmac_sha512(secret, secretlen, data, sizeof data, data))
|
if(!hmac_sha512(secret, secretlen, data, sizeof(data), data)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Outer HMAC */
|
/* Outer HMAC */
|
||||||
if(outlen >= mdlen) {
|
if(outlen >= mdlen) {
|
||||||
if(!hmac_sha512(secret, secretlen, data, sizeof data, out))
|
if(!hmac_sha512(secret, secretlen, data, sizeof(data), out)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
out += mdlen;
|
out += mdlen;
|
||||||
outlen -= mdlen;
|
outlen -= mdlen;
|
||||||
} else {
|
} else {
|
||||||
if(!hmac_sha512(secret, secretlen, data, sizeof data, hash))
|
if(!hmac_sha512(secret, secretlen, data, sizeof(data), hash)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(out, hash, outlen);
|
memcpy(out, hash, outlen);
|
||||||
out += outlen;
|
out += outlen;
|
||||||
outlen = 0;
|
outlen = 0;
|
||||||
|
|
|
@ -61,12 +61,15 @@ static bool pem_decode(FILE *fp, const char *header, uint8_t *buf, size_t size,
|
||||||
size_t i, j = 0;
|
size_t i, j = 0;
|
||||||
|
|
||||||
while(!feof(fp)) {
|
while(!feof(fp)) {
|
||||||
if(!fgets(line, sizeof line, fp))
|
if(!fgets(line, sizeof(line), fp)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if(!decode && !strncmp(line, "-----BEGIN ", 11)) {
|
if(!decode && !strncmp(line, "-----BEGIN ", 11)) {
|
||||||
if(!strncmp(line + 11, header, strlen(header)))
|
if(!strncmp(line + 11, header, strlen(header))) {
|
||||||
decode = true;
|
decode = true;
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,14 +77,18 @@ static bool pem_decode(FILE *fp, const char *header, uint8_t *buf, size_t size,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!decode)
|
if(!decode) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for(i = 0; line[i] >= ' '; i++) {
|
for(i = 0; line[i] >= ' '; i++) {
|
||||||
if((signed char)line[i] < 0 || b64d[(int)line[i]] == 0xff)
|
if((signed char)line[i] < 0 || b64d[(int)line[i]] == 0xff) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
word |= b64d[(int)line[i]] << shift;
|
word |= b64d[(int)line[i]] << shift;
|
||||||
shift -= 6;
|
shift -= 6;
|
||||||
|
|
||||||
if(shift <= 2) {
|
if(shift <= 2) {
|
||||||
if(j > size) {
|
if(j > size) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
|
@ -95,8 +102,10 @@ static bool pem_decode(FILE *fp, const char *header, uint8_t *buf, size_t size,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(outsize)
|
if(outsize) {
|
||||||
*outsize = j;
|
*outsize = j;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,20 +113,25 @@ static bool pem_decode(FILE *fp, const char *header, uint8_t *buf, size_t size,
|
||||||
// BER decoding functions
|
// BER decoding functions
|
||||||
|
|
||||||
static int ber_read_id(unsigned char **p, size_t *buflen) {
|
static int ber_read_id(unsigned char **p, size_t *buflen) {
|
||||||
if(*buflen <= 0)
|
if(*buflen <= 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if((**p & 0x1f) == 0x1f) {
|
if((**p & 0x1f) == 0x1f) {
|
||||||
int id = 0;
|
int id = 0;
|
||||||
bool more;
|
bool more;
|
||||||
|
|
||||||
while(*buflen > 0) {
|
while(*buflen > 0) {
|
||||||
id <<= 7;
|
id <<= 7;
|
||||||
id |= **p & 0x7f;
|
id |= **p & 0x7f;
|
||||||
more = *(*p)++ & 0x80;
|
more = *(*p)++ & 0x80;
|
||||||
(*buflen)--;
|
(*buflen)--;
|
||||||
if(!more)
|
|
||||||
|
if(!more) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
} else {
|
} else {
|
||||||
(*buflen)--;
|
(*buflen)--;
|
||||||
|
@ -126,15 +140,18 @@ static int ber_read_id(unsigned char **p, size_t *buflen) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t ber_read_len(unsigned char **p, size_t *buflen) {
|
static size_t ber_read_len(unsigned char **p, size_t *buflen) {
|
||||||
if(*buflen <= 0)
|
if(*buflen <= 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if(**p & 0x80) {
|
if(**p & 0x80) {
|
||||||
size_t result = 0;
|
size_t result = 0;
|
||||||
int len = *(*p)++ & 0x7f;
|
int len = *(*p)++ & 0x7f;
|
||||||
(*buflen)--;
|
(*buflen)--;
|
||||||
if(len > *buflen)
|
|
||||||
|
if(len > *buflen) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
while(len--) {
|
while(len--) {
|
||||||
result <<= 8;
|
result <<= 8;
|
||||||
|
@ -155,8 +172,10 @@ static bool ber_read_sequence(unsigned char **p, size_t *buflen, size_t *result)
|
||||||
size_t len = ber_read_len(p, buflen);
|
size_t len = ber_read_len(p, buflen);
|
||||||
|
|
||||||
if(tag == 0x10) {
|
if(tag == 0x10) {
|
||||||
if(result)
|
if(result) {
|
||||||
*result = len;
|
*result = len;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -168,11 +187,13 @@ static bool ber_read_mpi(unsigned char **p, size_t *buflen, gcry_mpi_t *mpi) {
|
||||||
size_t len = ber_read_len(p, buflen);
|
size_t len = ber_read_len(p, buflen);
|
||||||
gcry_error_t err = 0;
|
gcry_error_t err = 0;
|
||||||
|
|
||||||
if(tag != 0x02 || len > *buflen)
|
if(tag != 0x02 || len > *buflen) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if(mpi)
|
if(mpi) {
|
||||||
err = gcry_mpi_scan(mpi, GCRYMPI_FMT_USG, *p, len, NULL);
|
err = gcry_mpi_scan(mpi, GCRYMPI_FMT_USG, *p, len, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
*p += len;
|
*p += len;
|
||||||
*buflen -= len;
|
*buflen -= len;
|
||||||
|
@ -215,7 +236,7 @@ bool rsa_read_pem_public_key(rsa_t *rsa, FILE *fp) {
|
||||||
uint8_t derbuf[8096], *derp = derbuf;
|
uint8_t derbuf[8096], *derp = derbuf;
|
||||||
size_t derlen;
|
size_t derlen;
|
||||||
|
|
||||||
if(!pem_decode(fp, "RSA PUBLIC KEY", derbuf, sizeof derbuf, &derlen)) {
|
if(!pem_decode(fp, "RSA PUBLIC KEY", derbuf, sizeof(derbuf), &derlen)) {
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA public key: %s", strerror(errno));
|
logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA public key: %s", strerror(errno));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -235,7 +256,7 @@ bool rsa_read_pem_private_key(rsa_t *rsa, FILE *fp) {
|
||||||
uint8_t derbuf[8096], *derp = derbuf;
|
uint8_t derbuf[8096], *derp = derbuf;
|
||||||
size_t derlen;
|
size_t derlen;
|
||||||
|
|
||||||
if(!pem_decode(fp, "RSA PRIVATE KEY", derbuf, sizeof derbuf, &derlen)) {
|
if(!pem_decode(fp, "RSA PRIVATE KEY", derbuf, sizeof(derbuf), &derlen)) {
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA private key: %s", strerror(errno));
|
logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA private key: %s", strerror(errno));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -277,8 +298,10 @@ bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) {
|
||||||
gcry_mpi_powm(outmpi, inmpi, rsa->e, rsa->n);
|
gcry_mpi_powm(outmpi, inmpi, rsa->e, rsa->n);
|
||||||
|
|
||||||
int pad = len - (gcry_mpi_get_nbits(outmpi) + 7) / 8;
|
int pad = len - (gcry_mpi_get_nbits(outmpi) + 7) / 8;
|
||||||
while(pad--)
|
|
||||||
|
while(pad--) {
|
||||||
*(char *)out++ = 0;
|
*(char *)out++ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
check(gcry_mpi_print(GCRYMPI_FMT_USG, out, len, NULL, outmpi));
|
check(gcry_mpi_print(GCRYMPI_FMT_USG, out, len, NULL, outmpi));
|
||||||
|
|
||||||
|
@ -293,8 +316,10 @@ bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) {
|
||||||
gcry_mpi_powm(outmpi, inmpi, rsa->d, rsa->n);
|
gcry_mpi_powm(outmpi, inmpi, rsa->d, rsa->n);
|
||||||
|
|
||||||
int pad = len - (gcry_mpi_get_nbits(outmpi) + 7) / 8;
|
int pad = len - (gcry_mpi_get_nbits(outmpi) + 7) / 8;
|
||||||
while(pad--)
|
|
||||||
|
while(pad--) {
|
||||||
*(char *)out++ = 0;
|
*(char *)out++ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
check(gcry_mpi_print(GCRYMPI_FMT_USG, out, len, NULL, outmpi));
|
check(gcry_mpi_print(GCRYMPI_FMT_USG, out, len, NULL, outmpi));
|
||||||
|
|
||||||
|
|
|
@ -44,9 +44,11 @@ static bool pem_encode(FILE *fp, const char *header, uint8_t *buf, size_t size)
|
||||||
word = buf[i] << 16 | buf[i + 1] << 8 | buf[i + 2];
|
word = buf[i] << 16 | buf[i + 1] << 8 | buf[i + 2];
|
||||||
} else {
|
} else {
|
||||||
word = buf[i] << 16;
|
word = buf[i] << 16;
|
||||||
if(i == size - 2)
|
|
||||||
|
if(i == size - 2) {
|
||||||
word |= buf[i + 1] << 8;
|
word |= buf[i + 1] << 8;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
line[j++] = b64e[(word >> 18) ];
|
line[j++] = b64e[(word >> 18) ];
|
||||||
line[j++] = b64e[(word >> 12) & 0x3f];
|
line[j++] = b64e[(word >> 12) & 0x3f];
|
||||||
|
@ -62,8 +64,10 @@ static bool pem_encode(FILE *fp, const char *header, uint8_t *buf, size_t size)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(size % 3 > 0) {
|
if(size % 3 > 0) {
|
||||||
if(size % 3 > 1)
|
if(size % 3 > 1) {
|
||||||
line[j++] = '=';
|
line[j++] = '=';
|
||||||
|
}
|
||||||
|
|
||||||
line[j++] = '=';
|
line[j++] = '=';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,19 +86,24 @@ static bool pem_encode(FILE *fp, const char *header, uint8_t *buf, size_t size)
|
||||||
// BER encoding functions
|
// BER encoding functions
|
||||||
|
|
||||||
static bool ber_write_id(uint8_t **p, size_t *buflen, int id) {
|
static bool ber_write_id(uint8_t **p, size_t *buflen, int id) {
|
||||||
if(*buflen <= 0)
|
if(*buflen <= 0) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if(id >= 0x1f) {
|
if(id >= 0x1f) {
|
||||||
while(id) {
|
while(id) {
|
||||||
if(*buflen <= 0)
|
if(*buflen <= 0) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
(*buflen)--;
|
(*buflen)--;
|
||||||
**p = id & 0x7f;
|
**p = id & 0x7f;
|
||||||
id >>= 7;
|
id >>= 7;
|
||||||
if(id)
|
|
||||||
|
if(id) {
|
||||||
**p |= 0x80;
|
**p |= 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
(*p)++;
|
(*p)++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -107,14 +116,18 @@ static bool ber_write_id(uint8_t **p, size_t *buflen, int id) {
|
||||||
|
|
||||||
static bool ber_write_len(uint8_t **p, size_t *buflen, size_t len) {
|
static bool ber_write_len(uint8_t **p, size_t *buflen, size_t len) {
|
||||||
do {
|
do {
|
||||||
if(*buflen <= 0)
|
if(*buflen <= 0) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
(*buflen)--;
|
(*buflen)--;
|
||||||
**p = len & 0x7f;
|
**p = len & 0x7f;
|
||||||
len >>= 7;
|
len >>= 7;
|
||||||
if(len)
|
|
||||||
|
if(len) {
|
||||||
**p |= 0x80;
|
**p |= 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
(*p)++;
|
(*p)++;
|
||||||
} while(len);
|
} while(len);
|
||||||
|
|
||||||
|
@ -122,8 +135,9 @@ static bool ber_write_len(uint8_t **p, size_t *buflen, size_t len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ber_write_sequence(uint8_t **p, size_t *buflen, uint8_t *seqbuf, size_t seqlen) {
|
static bool ber_write_sequence(uint8_t **p, size_t *buflen, uint8_t *seqbuf, size_t seqlen) {
|
||||||
if(!ber_write_id(p, buflen, 0x10) || !ber_write_len(p, buflen, seqlen) || *buflen < seqlen)
|
if(!ber_write_id(p, buflen, 0x10) || !ber_write_len(p, buflen, seqlen) || *buflen < seqlen) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(*p, seqbuf, seqlen);
|
memcpy(*p, seqbuf, seqlen);
|
||||||
*p += seqlen;
|
*p += seqlen;
|
||||||
|
@ -134,15 +148,18 @@ static bool ber_write_sequence(uint8_t **p, size_t *buflen, uint8_t *seqbuf, siz
|
||||||
|
|
||||||
static bool ber_write_mpi(uint8_t **p, size_t *buflen, gcry_mpi_t mpi) {
|
static bool ber_write_mpi(uint8_t **p, size_t *buflen, gcry_mpi_t mpi) {
|
||||||
uint8_t tmpbuf[1024];
|
uint8_t tmpbuf[1024];
|
||||||
size_t tmplen = sizeof tmpbuf;
|
size_t tmplen = sizeof(tmpbuf);
|
||||||
gcry_error_t err;
|
gcry_error_t err;
|
||||||
|
|
||||||
err = gcry_mpi_aprint(GCRYMPI_FMT_USG, &tmpbuf, &tmplen, mpi);
|
err = gcry_mpi_aprint(GCRYMPI_FMT_USG, &tmpbuf, &tmplen, mpi);
|
||||||
if(err)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(!ber_write_id(p, buflen, 0x02) || !ber_write_len(p, buflen, tmplen) || *buflen < tmplen)
|
if(err) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!ber_write_id(p, buflen, 0x02) || !ber_write_len(p, buflen, tmplen) || *buflen < tmplen) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(*p, tmpbuf, tmplen);
|
memcpy(*p, tmpbuf, tmplen);
|
||||||
*p += tmplen;
|
*p += tmplen;
|
||||||
|
@ -158,8 +175,8 @@ bool rsa_write_pem_public_key(rsa_t *rsa, FILE *fp) {
|
||||||
uint8_t derbuf2[8096];
|
uint8_t derbuf2[8096];
|
||||||
uint8_t *derp1 = derbuf1;
|
uint8_t *derp1 = derbuf1;
|
||||||
uint8_t *derp2 = derbuf2;
|
uint8_t *derp2 = derbuf2;
|
||||||
size_t derlen1 = sizeof derbuf1;
|
size_t derlen1 = sizeof(derbuf1);
|
||||||
size_t derlen2 = sizeof derbuf2;
|
size_t derlen2 = sizeof(derbuf2);
|
||||||
|
|
||||||
if(!ber_write_mpi(&derp1, &derlen1, &rsa->n)
|
if(!ber_write_mpi(&derp1, &derlen1, &rsa->n)
|
||||||
|| !ber_write_mpi(&derp1, &derlen1, &rsa->e)
|
|| !ber_write_mpi(&derp1, &derlen1, &rsa->e)
|
||||||
|
@ -181,8 +198,8 @@ bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp) {
|
||||||
uint8_t derbuf2[8096];
|
uint8_t derbuf2[8096];
|
||||||
uint8_t *derp1 = derbuf1;
|
uint8_t *derp1 = derbuf1;
|
||||||
uint8_t *derp2 = derbuf2;
|
uint8_t *derp2 = derbuf2;
|
||||||
size_t derlen1 = sizeof derbuf1;
|
size_t derlen1 = sizeof(derbuf1);
|
||||||
size_t derlen2 = sizeof derbuf2;
|
size_t derlen2 = sizeof(derbuf2);
|
||||||
|
|
||||||
if(!ber_write_mpi(&derp1, &derlen1, &bits)
|
if(!ber_write_mpi(&derp1, &derlen1, &bits)
|
||||||
|| ber_write_mpi(&derp1, &derlen1, &rsa->n) // modulus
|
|| ber_write_mpi(&derp1, &derlen1, &rsa->n) // modulus
|
||||||
|
@ -192,8 +209,10 @@ bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp) {
|
||||||
|| ber_write_mpi(&derp1, &derlen1, &q)
|
|| ber_write_mpi(&derp1, &derlen1, &q)
|
||||||
|| ber_write_mpi(&derp1, &derlen1, &exp1)
|
|| ber_write_mpi(&derp1, &derlen1, &exp1)
|
||||||
|| ber_write_mpi(&derp1, &derlen1, &exp2)
|
|| ber_write_mpi(&derp1, &derlen1, &exp2)
|
||||||
|| ber_write_mpi(&derp1, &derlen1, &coeff))
|
|| ber_write_mpi(&derp1, &derlen1, &coeff)) {
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error while encoding RSA private key");
|
logger(DEBUG_ALWAYS, LOG_ERR, "Error while encoding RSA private key");
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
359
src/getopt.c
359
src/getopt.c
|
@ -183,8 +183,7 @@ int optopt = '?';
|
||||||
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
|
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
|
||||||
`--' can cause `getopt' to return -1 with `optind' != ARGC. */
|
`--' can cause `getopt' to return -1 with `optind' != ARGC. */
|
||||||
|
|
||||||
static enum
|
static enum {
|
||||||
{
|
|
||||||
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
|
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
|
||||||
} ordering;
|
} ordering;
|
||||||
|
|
||||||
|
@ -210,12 +209,14 @@ my_index (str, chr)
|
||||||
const char *str;
|
const char *str;
|
||||||
int chr;
|
int chr;
|
||||||
{
|
{
|
||||||
while (*str)
|
while(*str) {
|
||||||
{
|
if(*str == chr) {
|
||||||
if (*str == chr)
|
|
||||||
return (char *) str;
|
return (char *) str;
|
||||||
|
}
|
||||||
|
|
||||||
str++;
|
str++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,8 +263,7 @@ extern pid_t __libc_pid;
|
||||||
to getopt is that one passed to the process. */
|
to getopt is that one passed to the process. */
|
||||||
static void
|
static void
|
||||||
__attribute__((__unused__))
|
__attribute__((__unused__))
|
||||||
store_args_and_env (int argc, char *const *argv)
|
store_args_and_env(int argc, char *const *argv) {
|
||||||
{
|
|
||||||
/* XXX This is no good solution. We should rather copy the args so
|
/* XXX This is no good solution. We should rather copy the args so
|
||||||
that we can compare them later. But we must not use malloc(3). */
|
that we can compare them later. But we must not use malloc(3). */
|
||||||
original_argc = argc;
|
original_argc = argc;
|
||||||
|
@ -310,18 +310,18 @@ exchange (argv)
|
||||||
but it consists of two parts that need to be swapped next. */
|
but it consists of two parts that need to be swapped next. */
|
||||||
|
|
||||||
#ifdef _LIBC
|
#ifdef _LIBC
|
||||||
|
|
||||||
/* First make sure the handling of the `__getopt_nonoption_flags'
|
/* First make sure the handling of the `__getopt_nonoption_flags'
|
||||||
string can work normally. Our top argument must be in the range
|
string can work normally. Our top argument must be in the range
|
||||||
of the string. */
|
of the string. */
|
||||||
if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
|
if(nonoption_flags_len > 0 && top >= nonoption_flags_max_len) {
|
||||||
{
|
|
||||||
/* We must extend the array. The user plays games with us and
|
/* We must extend the array. The user plays games with us and
|
||||||
presents new arguments. */
|
presents new arguments. */
|
||||||
char *new_str = malloc(top + 1);
|
char *new_str = malloc(top + 1);
|
||||||
if (new_str == NULL)
|
|
||||||
|
if(new_str == NULL) {
|
||||||
nonoption_flags_len = nonoption_flags_max_len = 0;
|
nonoption_flags_len = nonoption_flags_max_len = 0;
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
memcpy(new_str, __getopt_nonoption_flags, nonoption_flags_max_len);
|
memcpy(new_str, __getopt_nonoption_flags, nonoption_flags_max_len);
|
||||||
memset(&new_str[nonoption_flags_max_len], '\0',
|
memset(&new_str[nonoption_flags_max_len], '\0',
|
||||||
top + 1 - nonoption_flags_max_len);
|
top + 1 - nonoption_flags_max_len);
|
||||||
|
@ -329,41 +329,38 @@ exchange (argv)
|
||||||
__getopt_nonoption_flags = new_str;
|
__getopt_nonoption_flags = new_str;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
while (top > middle && middle > bottom)
|
while(top > middle && middle > bottom) {
|
||||||
{
|
if(top - middle > middle - bottom) {
|
||||||
if (top - middle > middle - bottom)
|
|
||||||
{
|
|
||||||
/* Bottom segment is the short one. */
|
/* Bottom segment is the short one. */
|
||||||
int len = middle - bottom;
|
int len = middle - bottom;
|
||||||
register int i;
|
register int i;
|
||||||
|
|
||||||
/* Swap it with the top part of the top segment. */
|
/* Swap it with the top part of the top segment. */
|
||||||
for (i = 0; i < len; i++)
|
for(i = 0; i < len; i++) {
|
||||||
{
|
|
||||||
tem = argv[bottom + i];
|
tem = argv[bottom + i];
|
||||||
argv[bottom + i] = argv[top - (middle - bottom) + i];
|
argv[bottom + i] = argv[top - (middle - bottom) + i];
|
||||||
argv[top - (middle - bottom) + i] = tem;
|
argv[top - (middle - bottom) + i] = tem;
|
||||||
SWAP_FLAGS(bottom + i, top - (middle - bottom) + i);
|
SWAP_FLAGS(bottom + i, top - (middle - bottom) + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Exclude the moved bottom segment from further swapping. */
|
/* Exclude the moved bottom segment from further swapping. */
|
||||||
top -= len;
|
top -= len;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Top segment is the short one. */
|
/* Top segment is the short one. */
|
||||||
int len = top - middle;
|
int len = top - middle;
|
||||||
register int i;
|
register int i;
|
||||||
|
|
||||||
/* Swap it with the bottom part of the bottom segment. */
|
/* Swap it with the bottom part of the bottom segment. */
|
||||||
for (i = 0; i < len; i++)
|
for(i = 0; i < len; i++) {
|
||||||
{
|
|
||||||
tem = argv[bottom + i];
|
tem = argv[bottom + i];
|
||||||
argv[bottom + i] = argv[middle + i];
|
argv[bottom + i] = argv[middle + i];
|
||||||
argv[middle + i] = tem;
|
argv[middle + i] = tem;
|
||||||
SWAP_FLAGS(bottom + i, middle + i);
|
SWAP_FLAGS(bottom + i, middle + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Exclude the moved top segment from further swapping. */
|
/* Exclude the moved top segment from further swapping. */
|
||||||
bottom += len;
|
bottom += len;
|
||||||
}
|
}
|
||||||
|
@ -398,52 +395,52 @@ _getopt_initialize (argc, argv, optstring)
|
||||||
|
|
||||||
/* Determine how to handle the ordering of options and nonoptions. */
|
/* Determine how to handle the ordering of options and nonoptions. */
|
||||||
|
|
||||||
if (optstring[0] == '-')
|
if(optstring[0] == '-') {
|
||||||
{
|
|
||||||
ordering = RETURN_IN_ORDER;
|
ordering = RETURN_IN_ORDER;
|
||||||
++optstring;
|
++optstring;
|
||||||
}
|
} else if(optstring[0] == '+') {
|
||||||
else if (optstring[0] == '+')
|
|
||||||
{
|
|
||||||
ordering = REQUIRE_ORDER;
|
ordering = REQUIRE_ORDER;
|
||||||
++optstring;
|
++optstring;
|
||||||
}
|
} else if(posixly_correct != NULL) {
|
||||||
else if (posixly_correct != NULL)
|
|
||||||
ordering = REQUIRE_ORDER;
|
ordering = REQUIRE_ORDER;
|
||||||
else
|
} else {
|
||||||
ordering = PERMUTE;
|
ordering = PERMUTE;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef _LIBC
|
#ifdef _LIBC
|
||||||
|
|
||||||
if(posixly_correct == NULL
|
if(posixly_correct == NULL
|
||||||
&& argc == original_argc && argv == original_argv)
|
&& argc == original_argc && argv == original_argv) {
|
||||||
{
|
if(nonoption_flags_max_len == 0) {
|
||||||
if (nonoption_flags_max_len == 0)
|
|
||||||
{
|
|
||||||
if(__getopt_nonoption_flags == NULL
|
if(__getopt_nonoption_flags == NULL
|
||||||
|| __getopt_nonoption_flags[0] == '\0')
|
|| __getopt_nonoption_flags[0] == '\0') {
|
||||||
nonoption_flags_max_len = -1;
|
nonoption_flags_max_len = -1;
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
const char *orig_str = __getopt_nonoption_flags;
|
const char *orig_str = __getopt_nonoption_flags;
|
||||||
int len = nonoption_flags_max_len = strlen(orig_str);
|
int len = nonoption_flags_max_len = strlen(orig_str);
|
||||||
if (nonoption_flags_max_len < argc)
|
|
||||||
|
if(nonoption_flags_max_len < argc) {
|
||||||
nonoption_flags_max_len = argc;
|
nonoption_flags_max_len = argc;
|
||||||
|
}
|
||||||
|
|
||||||
__getopt_nonoption_flags =
|
__getopt_nonoption_flags =
|
||||||
(char *) malloc(nonoption_flags_max_len);
|
(char *) malloc(nonoption_flags_max_len);
|
||||||
if (__getopt_nonoption_flags == NULL)
|
|
||||||
|
if(__getopt_nonoption_flags == NULL) {
|
||||||
nonoption_flags_max_len = -1;
|
nonoption_flags_max_len = -1;
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
memcpy(__getopt_nonoption_flags, orig_str, len);
|
memcpy(__getopt_nonoption_flags, orig_str, len);
|
||||||
memset(&__getopt_nonoption_flags[len], '\0',
|
memset(&__getopt_nonoption_flags[len], '\0',
|
||||||
nonoption_flags_max_len - len);
|
nonoption_flags_max_len - len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nonoption_flags_len = nonoption_flags_max_len;
|
nonoption_flags_len = nonoption_flags_max_len;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
nonoption_flags_len = 0;
|
nonoption_flags_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return optstring;
|
return optstring;
|
||||||
|
@ -516,10 +513,11 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||||
{
|
{
|
||||||
optarg = NULL;
|
optarg = NULL;
|
||||||
|
|
||||||
if (optind == 0 || !__getopt_initialized)
|
if(optind == 0 || !__getopt_initialized) {
|
||||||
{
|
if(optind == 0) {
|
||||||
if (optind == 0)
|
|
||||||
optind = 1; /* Don't scan ARGV[0], the program name. */
|
optind = 1; /* Don't scan ARGV[0], the program name. */
|
||||||
|
}
|
||||||
|
|
||||||
optstring = _getopt_initialize(argc, argv, optstring);
|
optstring = _getopt_initialize(argc, argv, optstring);
|
||||||
__getopt_initialized = 1;
|
__getopt_initialized = 1;
|
||||||
}
|
}
|
||||||
|
@ -536,32 +534,36 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||||
#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
|
#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (nextchar == NULL || *nextchar == '\0')
|
if(nextchar == NULL || *nextchar == '\0') {
|
||||||
{
|
|
||||||
/* Advance to the next ARGV-element. */
|
/* Advance to the next ARGV-element. */
|
||||||
|
|
||||||
/* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
|
/* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
|
||||||
moved back by the user (who may also have changed the arguments). */
|
moved back by the user (who may also have changed the arguments). */
|
||||||
if (last_nonopt > optind)
|
if(last_nonopt > optind) {
|
||||||
last_nonopt = optind;
|
last_nonopt = optind;
|
||||||
if (first_nonopt > optind)
|
}
|
||||||
first_nonopt = optind;
|
|
||||||
|
|
||||||
if (ordering == PERMUTE)
|
if(first_nonopt > optind) {
|
||||||
{
|
first_nonopt = optind;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ordering == PERMUTE) {
|
||||||
/* If we have just processed some options following some non-options,
|
/* If we have just processed some options following some non-options,
|
||||||
exchange them so that the options come first. */
|
exchange them so that the options come first. */
|
||||||
|
|
||||||
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
if(first_nonopt != last_nonopt && last_nonopt != optind) {
|
||||||
exchange((char **) argv);
|
exchange((char **) argv);
|
||||||
else if (last_nonopt != optind)
|
} else if(last_nonopt != optind) {
|
||||||
first_nonopt = optind;
|
first_nonopt = optind;
|
||||||
|
}
|
||||||
|
|
||||||
/* Skip any additional non-options
|
/* Skip any additional non-options
|
||||||
and extend the range of non-options previously skipped. */
|
and extend the range of non-options previously skipped. */
|
||||||
|
|
||||||
while (optind < argc && NONOPTION_P)
|
while(optind < argc && NONOPTION_P) {
|
||||||
optind++;
|
optind++;
|
||||||
|
}
|
||||||
|
|
||||||
last_nonopt = optind;
|
last_nonopt = optind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -570,14 +572,15 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||||
then exchange with previous non-options as if it were an option,
|
then exchange with previous non-options as if it were an option,
|
||||||
then skip everything else like a non-option. */
|
then skip everything else like a non-option. */
|
||||||
|
|
||||||
if (optind != argc && !strcmp (argv[optind], "--"))
|
if(optind != argc && !strcmp(argv[optind], "--")) {
|
||||||
{
|
|
||||||
optind++;
|
optind++;
|
||||||
|
|
||||||
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
if(first_nonopt != last_nonopt && last_nonopt != optind) {
|
||||||
exchange((char **) argv);
|
exchange((char **) argv);
|
||||||
else if (first_nonopt == last_nonopt)
|
} else if(first_nonopt == last_nonopt) {
|
||||||
first_nonopt = optind;
|
first_nonopt = optind;
|
||||||
|
}
|
||||||
|
|
||||||
last_nonopt = argc;
|
last_nonopt = argc;
|
||||||
|
|
||||||
optind = argc;
|
optind = argc;
|
||||||
|
@ -586,22 +589,24 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||||
/* If we have done all the ARGV-elements, stop the scan
|
/* If we have done all the ARGV-elements, stop the scan
|
||||||
and back over any non-options that we skipped and permuted. */
|
and back over any non-options that we skipped and permuted. */
|
||||||
|
|
||||||
if (optind == argc)
|
if(optind == argc) {
|
||||||
{
|
|
||||||
/* Set the next-arg-index to point at the non-options
|
/* Set the next-arg-index to point at the non-options
|
||||||
that we previously skipped, so the caller will digest them. */
|
that we previously skipped, so the caller will digest them. */
|
||||||
if (first_nonopt != last_nonopt)
|
if(first_nonopt != last_nonopt) {
|
||||||
optind = first_nonopt;
|
optind = first_nonopt;
|
||||||
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we have come to a non-option and did not permute it,
|
/* If we have come to a non-option and did not permute it,
|
||||||
either stop the scan or describe it to the caller and pass it by. */
|
either stop the scan or describe it to the caller and pass it by. */
|
||||||
|
|
||||||
if (NONOPTION_P)
|
if(NONOPTION_P) {
|
||||||
{
|
if(ordering == REQUIRE_ORDER) {
|
||||||
if (ordering == REQUIRE_ORDER)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
optarg = argv[optind++];
|
optarg = argv[optind++];
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -630,8 +635,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||||
|
|
||||||
if(longopts != NULL
|
if(longopts != NULL
|
||||||
&& (argv[optind][1] == '-'
|
&& (argv[optind][1] == '-'
|
||||||
|| (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
|
|| (long_only && (argv[optind][2] || !my_index(optstring, argv[optind][1]))))) {
|
||||||
{
|
|
||||||
char *nameend;
|
char *nameend;
|
||||||
const struct option *p;
|
const struct option *p;
|
||||||
const struct option *pfound = NULL;
|
const struct option *pfound = NULL;
|
||||||
|
@ -646,53 +650,47 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||||
/* Test all long options for either exact match
|
/* Test all long options for either exact match
|
||||||
or abbreviated matches. */
|
or abbreviated matches. */
|
||||||
for(p = longopts, option_index = 0; p->name; p++, option_index++)
|
for(p = longopts, option_index = 0; p->name; p++, option_index++)
|
||||||
if (!strncmp (p->name, nextchar, nameend - nextchar))
|
if(!strncmp(p->name, nextchar, nameend - nextchar)) {
|
||||||
{
|
|
||||||
if((unsigned int)(nameend - nextchar)
|
if((unsigned int)(nameend - nextchar)
|
||||||
== (unsigned int) strlen (p->name))
|
== (unsigned int) strlen(p->name)) {
|
||||||
{
|
|
||||||
/* Exact match found. */
|
/* Exact match found. */
|
||||||
pfound = p;
|
pfound = p;
|
||||||
indfound = option_index;
|
indfound = option_index;
|
||||||
exact = 1;
|
exact = 1;
|
||||||
break;
|
break;
|
||||||
}
|
} else if(pfound == NULL) {
|
||||||
else if (pfound == NULL)
|
|
||||||
{
|
|
||||||
/* First nonexact match found. */
|
/* First nonexact match found. */
|
||||||
pfound = p;
|
pfound = p;
|
||||||
indfound = option_index;
|
indfound = option_index;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
/* Second or later nonexact match found. */
|
/* Second or later nonexact match found. */
|
||||||
|
{
|
||||||
ambig = 1;
|
ambig = 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ambig && !exact)
|
if(ambig && !exact) {
|
||||||
{
|
|
||||||
if(opterr)
|
if(opterr)
|
||||||
fprintf(stderr, "%s: option `%s' is ambiguous\n",
|
fprintf(stderr, "%s: option `%s' is ambiguous\n",
|
||||||
argv[0], argv[optind]);
|
argv[0], argv[optind]);
|
||||||
|
|
||||||
nextchar += strlen(nextchar);
|
nextchar += strlen(nextchar);
|
||||||
optind++;
|
optind++;
|
||||||
optopt = 0;
|
optopt = 0;
|
||||||
return '?';
|
return '?';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pfound != NULL)
|
if(pfound != NULL) {
|
||||||
{
|
|
||||||
option_index = indfound;
|
option_index = indfound;
|
||||||
optind++;
|
optind++;
|
||||||
if (*nameend)
|
|
||||||
{
|
if(*nameend) {
|
||||||
/* Don't test has_arg with >, because some C compilers don't
|
/* Don't test has_arg with >, because some C compilers don't
|
||||||
allow it to be used on enums. */
|
allow it to be used on enums. */
|
||||||
if (pfound->has_arg)
|
if(pfound->has_arg) {
|
||||||
optarg = nameend + 1;
|
optarg = nameend + 1;
|
||||||
else
|
} else {
|
||||||
{
|
if(opterr) {
|
||||||
if (opterr)
|
|
||||||
{
|
|
||||||
if(argv[optind - 1][1] == '-')
|
if(argv[optind - 1][1] == '-')
|
||||||
/* --option */
|
/* --option */
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
|
@ -710,30 +708,32 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||||
optopt = pfound->val;
|
optopt = pfound->val;
|
||||||
return '?';
|
return '?';
|
||||||
}
|
}
|
||||||
}
|
} else if(pfound->has_arg == 1) {
|
||||||
else if (pfound->has_arg == 1)
|
if(optind < argc) {
|
||||||
{
|
|
||||||
if (optind < argc)
|
|
||||||
optarg = argv[optind++];
|
optarg = argv[optind++];
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
if(opterr)
|
if(opterr)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"%s: option `%s' requires an argument\n",
|
"%s: option `%s' requires an argument\n",
|
||||||
argv[0], argv[optind - 1]);
|
argv[0], argv[optind - 1]);
|
||||||
|
|
||||||
nextchar += strlen(nextchar);
|
nextchar += strlen(nextchar);
|
||||||
optopt = pfound->val;
|
optopt = pfound->val;
|
||||||
return optstring[0] == ':' ? ':' : '?';
|
return optstring[0] == ':' ? ':' : '?';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nextchar += strlen(nextchar);
|
nextchar += strlen(nextchar);
|
||||||
if (longind != NULL)
|
|
||||||
|
if(longind != NULL) {
|
||||||
*longind = option_index;
|
*longind = option_index;
|
||||||
if (pfound->flag)
|
}
|
||||||
{
|
|
||||||
|
if(pfound->flag) {
|
||||||
*(pfound->flag) = pfound->val;
|
*(pfound->flag) = pfound->val;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pfound->val;
|
return pfound->val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -742,10 +742,8 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||||
option, then it's an error.
|
option, then it's an error.
|
||||||
Otherwise interpret it as a short option. */
|
Otherwise interpret it as a short option. */
|
||||||
if(!long_only || argv[optind][1] == '-'
|
if(!long_only || argv[optind][1] == '-'
|
||||||
|| my_index (optstring, *nextchar) == NULL)
|
|| my_index(optstring, *nextchar) == NULL) {
|
||||||
{
|
if(opterr) {
|
||||||
if (opterr)
|
|
||||||
{
|
|
||||||
if(argv[optind][1] == '-')
|
if(argv[optind][1] == '-')
|
||||||
/* --option */
|
/* --option */
|
||||||
fprintf(stderr, "%s: unrecognized option `--%s'\n",
|
fprintf(stderr, "%s: unrecognized option `--%s'\n",
|
||||||
|
@ -755,6 +753,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||||
fprintf(stderr, "%s: unrecognized option `%c%s'\n",
|
fprintf(stderr, "%s: unrecognized option `%c%s'\n",
|
||||||
argv[0], argv[optind][0], nextchar);
|
argv[0], argv[optind][0], nextchar);
|
||||||
}
|
}
|
||||||
|
|
||||||
nextchar = (char *) "";
|
nextchar = (char *) "";
|
||||||
optind++;
|
optind++;
|
||||||
optopt = 0;
|
optopt = 0;
|
||||||
|
@ -769,13 +768,12 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||||
char *temp = my_index(optstring, c);
|
char *temp = my_index(optstring, c);
|
||||||
|
|
||||||
/* Increment `optind' when we start to process its last character. */
|
/* Increment `optind' when we start to process its last character. */
|
||||||
if (*nextchar == '\0')
|
if(*nextchar == '\0') {
|
||||||
++optind;
|
++optind;
|
||||||
|
}
|
||||||
|
|
||||||
if (temp == NULL || c == ':')
|
if(temp == NULL || c == ':') {
|
||||||
{
|
if(opterr) {
|
||||||
if (opterr)
|
|
||||||
{
|
|
||||||
if(posixly_correct)
|
if(posixly_correct)
|
||||||
/* 1003.2 specifies the format of this message. */
|
/* 1003.2 specifies the format of this message. */
|
||||||
fprintf(stderr, "%s: illegal option -- %c\n",
|
fprintf(stderr, "%s: illegal option -- %c\n",
|
||||||
|
@ -784,12 +782,13 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||||
fprintf(stderr, "%s: invalid option -- %c\n",
|
fprintf(stderr, "%s: invalid option -- %c\n",
|
||||||
argv[0], c);
|
argv[0], c);
|
||||||
}
|
}
|
||||||
|
|
||||||
optopt = c;
|
optopt = c;
|
||||||
return '?';
|
return '?';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convenience. Treat POSIX -W foo same as long option --foo */
|
/* Convenience. Treat POSIX -W foo same as long option --foo */
|
||||||
if (temp[0] == 'W' && temp[1] == ';')
|
if(temp[0] == 'W' && temp[1] == ';') {
|
||||||
{
|
|
||||||
char *nameend;
|
char *nameend;
|
||||||
const struct option *p;
|
const struct option *p;
|
||||||
const struct option *pfound = NULL;
|
const struct option *pfound = NULL;
|
||||||
|
@ -799,32 +798,33 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||||
int option_index;
|
int option_index;
|
||||||
|
|
||||||
/* This is an option that requires an argument. */
|
/* This is an option that requires an argument. */
|
||||||
if (*nextchar != '\0')
|
if(*nextchar != '\0') {
|
||||||
{
|
|
||||||
optarg = nextchar;
|
optarg = nextchar;
|
||||||
/* If we end this ARGV-element by taking the rest as an arg,
|
/* If we end this ARGV-element by taking the rest as an arg,
|
||||||
we must advance to the next element now. */
|
we must advance to the next element now. */
|
||||||
optind++;
|
optind++;
|
||||||
}
|
} else if(optind == argc) {
|
||||||
else if (optind == argc)
|
if(opterr) {
|
||||||
{
|
|
||||||
if (opterr)
|
|
||||||
{
|
|
||||||
/* 1003.2 specifies the format of this message. */
|
/* 1003.2 specifies the format of this message. */
|
||||||
fprintf(stderr, "%s: option requires an argument -- %c\n",
|
fprintf(stderr, "%s: option requires an argument -- %c\n",
|
||||||
argv[0], c);
|
argv[0], c);
|
||||||
}
|
}
|
||||||
|
|
||||||
optopt = c;
|
optopt = c;
|
||||||
if (optstring[0] == ':')
|
|
||||||
|
if(optstring[0] == ':') {
|
||||||
c = ':';
|
c = ':';
|
||||||
else
|
} else {
|
||||||
c = '?';
|
c = '?';
|
||||||
return c;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
return c;
|
||||||
|
} else
|
||||||
/* We already incremented `optind' once;
|
/* We already incremented `optind' once;
|
||||||
increment it again when taking next ARGV-elt as argument. */
|
increment it again when taking next ARGV-elt as argument. */
|
||||||
|
{
|
||||||
optarg = argv[optind++];
|
optarg = argv[optind++];
|
||||||
|
}
|
||||||
|
|
||||||
/* optarg is now the argument, see if it's in the
|
/* optarg is now the argument, see if it's in the
|
||||||
table of longopts. */
|
table of longopts. */
|
||||||
|
@ -835,46 +835,43 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||||
/* Test all long options for either exact match
|
/* Test all long options for either exact match
|
||||||
or abbreviated matches. */
|
or abbreviated matches. */
|
||||||
for(p = longopts, option_index = 0; p->name; p++, option_index++)
|
for(p = longopts, option_index = 0; p->name; p++, option_index++)
|
||||||
if (!strncmp (p->name, nextchar, nameend - nextchar))
|
if(!strncmp(p->name, nextchar, nameend - nextchar)) {
|
||||||
{
|
if((unsigned int)(nameend - nextchar) == strlen(p->name)) {
|
||||||
if ((unsigned int) (nameend - nextchar) == strlen (p->name))
|
|
||||||
{
|
|
||||||
/* Exact match found. */
|
/* Exact match found. */
|
||||||
pfound = p;
|
pfound = p;
|
||||||
indfound = option_index;
|
indfound = option_index;
|
||||||
exact = 1;
|
exact = 1;
|
||||||
break;
|
break;
|
||||||
}
|
} else if(pfound == NULL) {
|
||||||
else if (pfound == NULL)
|
|
||||||
{
|
|
||||||
/* First nonexact match found. */
|
/* First nonexact match found. */
|
||||||
pfound = p;
|
pfound = p;
|
||||||
indfound = option_index;
|
indfound = option_index;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
/* Second or later nonexact match found. */
|
/* Second or later nonexact match found. */
|
||||||
|
{
|
||||||
ambig = 1;
|
ambig = 1;
|
||||||
}
|
}
|
||||||
if (ambig && !exact)
|
}
|
||||||
{
|
|
||||||
|
if(ambig && !exact) {
|
||||||
if(opterr)
|
if(opterr)
|
||||||
fprintf(stderr, "%s: option `-W %s' is ambiguous\n",
|
fprintf(stderr, "%s: option `-W %s' is ambiguous\n",
|
||||||
argv[0], argv[optind]);
|
argv[0], argv[optind]);
|
||||||
|
|
||||||
nextchar += strlen(nextchar);
|
nextchar += strlen(nextchar);
|
||||||
optind++;
|
optind++;
|
||||||
return '?';
|
return '?';
|
||||||
}
|
}
|
||||||
if (pfound != NULL)
|
|
||||||
{
|
if(pfound != NULL) {
|
||||||
option_index = indfound;
|
option_index = indfound;
|
||||||
if (*nameend)
|
|
||||||
{
|
if(*nameend) {
|
||||||
/* Don't test has_arg with >, because some C compilers don't
|
/* Don't test has_arg with >, because some C compilers don't
|
||||||
allow it to be used on enums. */
|
allow it to be used on enums. */
|
||||||
if (pfound->has_arg)
|
if(pfound->has_arg) {
|
||||||
optarg = nameend + 1;
|
optarg = nameend + 1;
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
if(opterr)
|
if(opterr)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"%s: option `-W %s' doesn't allow an argument\n",
|
"%s: option `-W %s' doesn't allow an argument\n",
|
||||||
|
@ -883,80 +880,82 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||||
nextchar += strlen(nextchar);
|
nextchar += strlen(nextchar);
|
||||||
return '?';
|
return '?';
|
||||||
}
|
}
|
||||||
}
|
} else if(pfound->has_arg == 1) {
|
||||||
else if (pfound->has_arg == 1)
|
if(optind < argc) {
|
||||||
{
|
|
||||||
if (optind < argc)
|
|
||||||
optarg = argv[optind++];
|
optarg = argv[optind++];
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
if(opterr)
|
if(opterr)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"%s: option `%s' requires an argument\n",
|
"%s: option `%s' requires an argument\n",
|
||||||
argv[0], argv[optind - 1]);
|
argv[0], argv[optind - 1]);
|
||||||
|
|
||||||
nextchar += strlen(nextchar);
|
nextchar += strlen(nextchar);
|
||||||
return optstring[0] == ':' ? ':' : '?';
|
return optstring[0] == ':' ? ':' : '?';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nextchar += strlen(nextchar);
|
nextchar += strlen(nextchar);
|
||||||
if (longind != NULL)
|
|
||||||
|
if(longind != NULL) {
|
||||||
*longind = option_index;
|
*longind = option_index;
|
||||||
if (pfound->flag)
|
}
|
||||||
{
|
|
||||||
|
if(pfound->flag) {
|
||||||
*(pfound->flag) = pfound->val;
|
*(pfound->flag) = pfound->val;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pfound->val;
|
return pfound->val;
|
||||||
}
|
}
|
||||||
|
|
||||||
nextchar = NULL;
|
nextchar = NULL;
|
||||||
return 'W'; /* Let the application handle it. */
|
return 'W'; /* Let the application handle it. */
|
||||||
}
|
}
|
||||||
if (temp[1] == ':')
|
|
||||||
{
|
if(temp[1] == ':') {
|
||||||
if (temp[2] == ':')
|
if(temp[2] == ':') {
|
||||||
{
|
|
||||||
/* This is an option that accepts an argument optionally. */
|
/* This is an option that accepts an argument optionally. */
|
||||||
if (*nextchar != '\0')
|
if(*nextchar != '\0') {
|
||||||
{
|
|
||||||
optarg = nextchar;
|
optarg = nextchar;
|
||||||
optind++;
|
optind++;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
optarg = NULL;
|
optarg = NULL;
|
||||||
nextchar = NULL;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
nextchar = NULL;
|
||||||
|
} else {
|
||||||
/* This is an option that requires an argument. */
|
/* This is an option that requires an argument. */
|
||||||
if (*nextchar != '\0')
|
if(*nextchar != '\0') {
|
||||||
{
|
|
||||||
optarg = nextchar;
|
optarg = nextchar;
|
||||||
/* If we end this ARGV-element by taking the rest as an arg,
|
/* If we end this ARGV-element by taking the rest as an arg,
|
||||||
we must advance to the next element now. */
|
we must advance to the next element now. */
|
||||||
optind++;
|
optind++;
|
||||||
}
|
} else if(optind == argc) {
|
||||||
else if (optind == argc)
|
if(opterr) {
|
||||||
{
|
|
||||||
if (opterr)
|
|
||||||
{
|
|
||||||
/* 1003.2 specifies the format of this message. */
|
/* 1003.2 specifies the format of this message. */
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"%s: option requires an argument -- %c\n",
|
"%s: option requires an argument -- %c\n",
|
||||||
argv[0], c);
|
argv[0], c);
|
||||||
}
|
}
|
||||||
|
|
||||||
optopt = c;
|
optopt = c;
|
||||||
if (optstring[0] == ':')
|
|
||||||
|
if(optstring[0] == ':') {
|
||||||
c = ':';
|
c = ':';
|
||||||
else
|
} else {
|
||||||
c = '?';
|
c = '?';
|
||||||
}
|
}
|
||||||
else
|
} else
|
||||||
/* We already incremented `optind' once;
|
/* We already incremented `optind' once;
|
||||||
increment it again when taking next ARGV-elt as argument. */
|
increment it again when taking next ARGV-elt as argument. */
|
||||||
|
{
|
||||||
optarg = argv[optind++];
|
optarg = argv[optind++];
|
||||||
|
}
|
||||||
|
|
||||||
nextchar = NULL;
|
nextchar = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -988,16 +987,16 @@ main (argc, argv)
|
||||||
int c;
|
int c;
|
||||||
int digit_optind = 0;
|
int digit_optind = 0;
|
||||||
|
|
||||||
while (1)
|
while(1) {
|
||||||
{
|
|
||||||
int this_option_optind = optind ? optind : 1;
|
int this_option_optind = optind ? optind : 1;
|
||||||
|
|
||||||
c = getopt(argc, argv, "abc:d:0123456789");
|
c = getopt(argc, argv, "abc:d:0123456789");
|
||||||
if (c == -1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
switch (c)
|
if(c == -1) {
|
||||||
{
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(c) {
|
||||||
case '0':
|
case '0':
|
||||||
case '1':
|
case '1':
|
||||||
case '2':
|
case '2':
|
||||||
|
@ -1008,8 +1007,10 @@ main (argc, argv)
|
||||||
case '7':
|
case '7':
|
||||||
case '8':
|
case '8':
|
||||||
case '9':
|
case '9':
|
||||||
if (digit_optind != 0 && digit_optind != this_option_optind)
|
if(digit_optind != 0 && digit_optind != this_option_optind) {
|
||||||
printf("digits occur in two different argv-elements.\n");
|
printf("digits occur in two different argv-elements.\n");
|
||||||
|
}
|
||||||
|
|
||||||
digit_optind = this_option_optind;
|
digit_optind = this_option_optind;
|
||||||
printf("option %c\n", c);
|
printf("option %c\n", c);
|
||||||
break;
|
break;
|
||||||
|
@ -1034,11 +1035,13 @@ main (argc, argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optind < argc)
|
if(optind < argc) {
|
||||||
{
|
|
||||||
printf("non-option ARGV-elements: ");
|
printf("non-option ARGV-elements: ");
|
||||||
while (optind < argc)
|
|
||||||
|
while(optind < argc) {
|
||||||
printf("%s ", argv[optind++]);
|
printf("%s ", argv[optind++]);
|
||||||
|
}
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
#ifndef TINC_GETOPT_H
|
||||||
|
#define TINC_GETOPT_H
|
||||||
|
|
||||||
/* Declarations for getopt.
|
/* Declarations for getopt.
|
||||||
Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc.
|
Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
@ -78,8 +81,7 @@ extern int optopt;
|
||||||
one). For long options that have a zero `flag' field, `getopt'
|
one). For long options that have a zero `flag' field, `getopt'
|
||||||
returns the contents of the `val' field. */
|
returns the contents of the `val' field. */
|
||||||
|
|
||||||
struct option
|
struct option {
|
||||||
{
|
|
||||||
#if defined (__STDC__) && __STDC__
|
#if defined (__STDC__) && __STDC__
|
||||||
const char *name;
|
const char *name;
|
||||||
#else
|
#else
|
||||||
|
@ -130,4 +132,4 @@ extern int _getopt_internal ();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _GETOPT_H */
|
#endif
|
||||||
|
|
|
@ -106,12 +106,10 @@ main (argc, argv)
|
||||||
int c;
|
int c;
|
||||||
int digit_optind = 0;
|
int digit_optind = 0;
|
||||||
|
|
||||||
while (1)
|
while(1) {
|
||||||
{
|
|
||||||
int this_option_optind = optind ? optind : 1;
|
int this_option_optind = optind ? optind : 1;
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
static struct option long_options[] =
|
static struct option long_options[] = {
|
||||||
{
|
|
||||||
{"add", 1, 0, 0},
|
{"add", 1, 0, 0},
|
||||||
{"append", 0, 0, 0},
|
{"append", 0, 0, 0},
|
||||||
{"delete", 1, 0, 0},
|
{"delete", 1, 0, 0},
|
||||||
|
@ -123,15 +121,19 @@ main (argc, argv)
|
||||||
|
|
||||||
c = getopt_long(argc, argv, "abc:d:0123456789",
|
c = getopt_long(argc, argv, "abc:d:0123456789",
|
||||||
long_options, &option_index);
|
long_options, &option_index);
|
||||||
if (c == -1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
switch (c)
|
if(c == -1) {
|
||||||
{
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(c) {
|
||||||
case 0:
|
case 0:
|
||||||
printf("option %s", long_options[option_index].name);
|
printf("option %s", long_options[option_index].name);
|
||||||
if (optarg)
|
|
||||||
|
if(optarg) {
|
||||||
printf(" with arg %s", optarg);
|
printf(" with arg %s", optarg);
|
||||||
|
}
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -145,8 +147,10 @@ main (argc, argv)
|
||||||
case '7':
|
case '7':
|
||||||
case '8':
|
case '8':
|
||||||
case '9':
|
case '9':
|
||||||
if (digit_optind != 0 && digit_optind != this_option_optind)
|
if(digit_optind != 0 && digit_optind != this_option_optind) {
|
||||||
printf("digits occur in two different argv-elements.\n");
|
printf("digits occur in two different argv-elements.\n");
|
||||||
|
}
|
||||||
|
|
||||||
digit_optind = this_option_optind;
|
digit_optind = this_option_optind;
|
||||||
printf("option %c\n", c);
|
printf("option %c\n", c);
|
||||||
break;
|
break;
|
||||||
|
@ -175,11 +179,13 @@ main (argc, argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optind < argc)
|
if(optind < argc) {
|
||||||
{
|
|
||||||
printf("non-option ARGV-elements: ");
|
printf("non-option ARGV-elements: ");
|
||||||
while (optind < argc)
|
|
||||||
|
while(optind < argc) {
|
||||||
printf("%s ", argv[optind++]);
|
printf("%s ", argv[optind++]);
|
||||||
|
}
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
54
src/graph.c
54
src/graph.c
|
@ -68,15 +68,17 @@
|
||||||
static void mst_kruskal(void) {
|
static void mst_kruskal(void) {
|
||||||
/* Clear MST status on connections */
|
/* Clear MST status on connections */
|
||||||
|
|
||||||
for list_each(connection_t, c, connection_list)
|
for list_each(connection_t, c, connection_list) {
|
||||||
c->status.mst = false;
|
c->status.mst = false;
|
||||||
|
}
|
||||||
|
|
||||||
logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Running Kruskal's algorithm:");
|
logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Running Kruskal's algorithm:");
|
||||||
|
|
||||||
/* Clear visited status on nodes */
|
/* Clear visited status on nodes */
|
||||||
|
|
||||||
for splay_each(node_t, n, node_tree)
|
for splay_each(node_t, n, node_tree) {
|
||||||
n->status.visited = false;
|
n->status.visited = false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Starting point */
|
/* Starting point */
|
||||||
|
|
||||||
|
@ -100,11 +102,13 @@ static void mst_kruskal(void) {
|
||||||
e->from->status.visited = true;
|
e->from->status.visited = true;
|
||||||
e->to->status.visited = true;
|
e->to->status.visited = true;
|
||||||
|
|
||||||
if(e->connection)
|
if(e->connection) {
|
||||||
e->connection->status.mst = true;
|
e->connection->status.mst = true;
|
||||||
|
}
|
||||||
|
|
||||||
if(e->reverse->connection)
|
if(e->reverse->connection) {
|
||||||
e->reverse->connection->status.mst = true;
|
e->reverse->connection->status.mst = true;
|
||||||
|
}
|
||||||
|
|
||||||
logger(DEBUG_SCARY_THINGS, LOG_DEBUG, " Adding edge %s - %s weight %d", e->from->name, e->to->name, e->weight);
|
logger(DEBUG_SCARY_THINGS, LOG_DEBUG, " Adding edge %s - %s weight %d", e->from->name, e->to->name, e->weight);
|
||||||
|
|
||||||
|
@ -145,12 +149,14 @@ static void sssp_bfs(void) {
|
||||||
for list_each(node_t, n, todo_list) { /* "n" is the node from which we start */
|
for list_each(node_t, n, todo_list) { /* "n" is the node from which we start */
|
||||||
logger(DEBUG_SCARY_THINGS, LOG_DEBUG, " Examining edges from %s", n->name);
|
logger(DEBUG_SCARY_THINGS, LOG_DEBUG, " Examining edges from %s", n->name);
|
||||||
|
|
||||||
if(n->distance < 0)
|
if(n->distance < 0) {
|
||||||
abort();
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
for splay_each(edge_t, e, n->edge_tree) { /* "e" is the edge connected to "from" */
|
for splay_each(edge_t, e, n->edge_tree) { /* "e" is the edge connected to "from" */
|
||||||
if(!e->reverse || e->to == myself)
|
if(!e->reverse || e->to == myself) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* Situation:
|
/* Situation:
|
||||||
|
|
||||||
|
@ -173,13 +179,15 @@ static void sssp_bfs(void) {
|
||||||
|
|
||||||
if(e->to->status.visited
|
if(e->to->status.visited
|
||||||
&& (!e->to->status.indirect || indirect)
|
&& (!e->to->status.indirect || indirect)
|
||||||
&& (e->to->distance != n->distance + 1 || e->weight >= e->to->prevedge->weight))
|
&& (e->to->distance != n->distance + 1 || e->weight >= e->to->prevedge->weight)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Only update nexthop if it doesn't increase the path length
|
// Only update nexthop if it doesn't increase the path length
|
||||||
|
|
||||||
if(!e->to->status.visited || (e->to->distance == n->distance + 1 && e->weight >= e->to->prevedge->weight))
|
if(!e->to->status.visited || (e->to->distance == n->distance + 1 && e->weight >= e->to->prevedge->weight)) {
|
||||||
e->to->nexthop = (n->nexthop == myself) ? e->to : n->nexthop;
|
e->to->nexthop = (n->nexthop == myself) ? e->to : n->nexthop;
|
||||||
|
}
|
||||||
|
|
||||||
e->to->status.visited = true;
|
e->to->status.visited = true;
|
||||||
e->to->status.indirect = indirect;
|
e->to->status.indirect = indirect;
|
||||||
|
@ -188,8 +196,9 @@ static void sssp_bfs(void) {
|
||||||
e->to->options = e->options;
|
e->to->options = e->options;
|
||||||
e->to->distance = n->distance + 1;
|
e->to->distance = n->distance + 1;
|
||||||
|
|
||||||
if(!e->to->status.reachable || (e->to->address.sa.sa_family == AF_UNSPEC && e->address.sa.sa_family != AF_UNKNOWN))
|
if(!e->to->status.reachable || (e->to->address.sa.sa_family == AF_UNSPEC && e->address.sa.sa_family != AF_UNKNOWN)) {
|
||||||
update_node_udp(e->to, &e->address);
|
update_node_udp(e->to, &e->address);
|
||||||
|
}
|
||||||
|
|
||||||
list_insert_tail(todo_list, e->to);
|
list_insert_tail(todo_list, e->to);
|
||||||
}
|
}
|
||||||
|
@ -207,6 +216,7 @@ static void check_reachability(void) {
|
||||||
int reachable_count = 0;
|
int reachable_count = 0;
|
||||||
int became_reachable_count = 0;
|
int became_reachable_count = 0;
|
||||||
int became_unreachable_count = 0;
|
int became_unreachable_count = 0;
|
||||||
|
|
||||||
for splay_each(node_t, n, node_tree) {
|
for splay_each(node_t, n, node_tree) {
|
||||||
if(n->status.visited != n->status.reachable) {
|
if(n->status.visited != n->status.reachable) {
|
||||||
n->status.reachable = !n->status.reachable;
|
n->status.reachable = !n->status.reachable;
|
||||||
|
@ -215,25 +225,32 @@ static void check_reachability(void) {
|
||||||
if(n->status.reachable) {
|
if(n->status.reachable) {
|
||||||
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Node %s (%s) became reachable",
|
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Node %s (%s) became reachable",
|
||||||
n->name, n->hostname);
|
n->name, n->hostname);
|
||||||
if (n != myself)
|
|
||||||
|
if(n != myself) {
|
||||||
became_reachable_count++;
|
became_reachable_count++;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Node %s (%s) became unreachable",
|
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Node %s (%s) became unreachable",
|
||||||
n->name, n->hostname);
|
n->name, n->hostname);
|
||||||
if (n != myself)
|
|
||||||
|
if(n != myself) {
|
||||||
became_unreachable_count++;
|
became_unreachable_count++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(experimental && OPTION_VERSION(n->options) >= 2)
|
if(experimental && OPTION_VERSION(n->options) >= 2) {
|
||||||
n->status.sptps = true;
|
n->status.sptps = true;
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO: only clear status.validkey if node is unreachable? */
|
/* TODO: only clear status.validkey if node is unreachable? */
|
||||||
|
|
||||||
n->status.validkey = false;
|
n->status.validkey = false;
|
||||||
|
|
||||||
if(n->status.sptps) {
|
if(n->status.sptps) {
|
||||||
sptps_stop(&n->sptps);
|
sptps_stop(&n->sptps);
|
||||||
n->status.waitingforkey = false;
|
n->status.waitingforkey = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
n->last_req_key = 0;
|
n->last_req_key = 0;
|
||||||
|
|
||||||
n->status.udp_confirmed = false;
|
n->status.udp_confirmed = false;
|
||||||
|
@ -269,26 +286,29 @@ static void check_reachability(void) {
|
||||||
|
|
||||||
if(!n->status.reachable) {
|
if(!n->status.reachable) {
|
||||||
update_node_udp(n, NULL);
|
update_node_udp(n, NULL);
|
||||||
memset(&n->status, 0, sizeof n->status);
|
memset(&n->status, 0, sizeof(n->status));
|
||||||
n->options = 0;
|
n->options = 0;
|
||||||
} else if(n->connection) {
|
} else if(n->connection) {
|
||||||
// Speed up UDP probing by sending our key.
|
// Speed up UDP probing by sending our key.
|
||||||
if(!n->status.sptps)
|
if(!n->status.sptps) {
|
||||||
send_ans_key(n);
|
send_ans_key(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(n->status.reachable && n != myself)
|
if(n->status.reachable && n != myself) {
|
||||||
reachable_count++;
|
reachable_count++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(device_standby) {
|
if(device_standby) {
|
||||||
if (reachable_count == 0 && became_unreachable_count > 0)
|
if(reachable_count == 0 && became_unreachable_count > 0) {
|
||||||
device_disable();
|
device_disable();
|
||||||
else if (reachable_count > 0 && reachable_count == became_reachable_count)
|
} else if(reachable_count > 0 && reachable_count == became_reachable_count) {
|
||||||
device_enable();
|
device_enable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void graph(void) {
|
void graph(void) {
|
||||||
subnet_cache_flush();
|
subnet_cache_flush();
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
#ifndef TINC_GRAPH_H
|
||||||
|
#define TINC_GRAPH_H
|
||||||
|
|
||||||
/*
|
/*
|
||||||
graph.h -- header for graph.c
|
graph.h -- header for graph.c
|
||||||
Copyright (C) 2001-2012 Guus Sliepen <guus@tinc-vpn.org>,
|
Copyright (C) 2001-2012 Guus Sliepen <guus@tinc-vpn.org>,
|
||||||
|
@ -18,10 +21,7 @@
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TINC_GRAPH_H__
|
|
||||||
#define __TINC_GRAPH_H__
|
|
||||||
|
|
||||||
extern void graph(void);
|
extern void graph(void);
|
||||||
extern void dump_graph(void);
|
extern void dump_graph(void);
|
||||||
|
|
||||||
#endif /* __TINC_GRAPH_H__ */
|
#endif
|
||||||
|
|
36
src/hash.c
36
src/hash.c
|
@ -27,36 +27,44 @@
|
||||||
static uint32_t hash_function(const void *p, size_t len) {
|
static uint32_t hash_function(const void *p, size_t len) {
|
||||||
const uint8_t *q = p;
|
const uint8_t *q = p;
|
||||||
uint32_t hash = 0;
|
uint32_t hash = 0;
|
||||||
|
|
||||||
while(true) {
|
while(true) {
|
||||||
for(int i = len > 4 ? 4 : len; --i;)
|
for(int i = len > 4 ? 4 : len; --i;) {
|
||||||
hash += (uint32_t)q[len - i] << (8 * i);
|
hash += (uint32_t)q[len - i] << (8 * i);
|
||||||
|
}
|
||||||
|
|
||||||
hash *= 0x9e370001UL; // Golden ratio prime.
|
hash *= 0x9e370001UL; // Golden ratio prime.
|
||||||
if(len <= 4)
|
|
||||||
|
if(len <= 4) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
len -= 4;
|
len -= 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Map 32 bits int onto 0..n-1, without throwing away too many bits if n is 2^8 or 2^16 */
|
/* Map 32 bits int onto 0..n-1, without throwing away too many bits if n is 2^8 or 2^16 */
|
||||||
|
|
||||||
static uint32_t modulo(uint32_t hash, size_t n) {
|
static uint32_t modulo(uint32_t hash, size_t n) {
|
||||||
if(n == 0x100)
|
if(n == 0x100) {
|
||||||
return (hash >> 24) ^ ((hash >> 16) & 0xff) ^ ((hash >> 8) & 0xff) ^ (hash & 0xff);
|
return (hash >> 24) ^ ((hash >> 16) & 0xff) ^ ((hash >> 8) & 0xff) ^ (hash & 0xff);
|
||||||
else if(n == 0x10000)
|
} else if(n == 0x10000) {
|
||||||
return (hash >> 16) ^ (hash & 0xffff);
|
return (hash >> 16) ^ (hash & 0xffff);
|
||||||
else
|
} else {
|
||||||
return hash % n;
|
return hash % n;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* (De)allocation */
|
/* (De)allocation */
|
||||||
|
|
||||||
hash_t *hash_alloc(size_t n, size_t size) {
|
hash_t *hash_alloc(size_t n, size_t size) {
|
||||||
hash_t *hash = xzalloc(sizeof *hash);
|
hash_t *hash = xzalloc(sizeof(*hash));
|
||||||
hash->n = n;
|
hash->n = n;
|
||||||
hash->size = size;
|
hash->size = size;
|
||||||
hash->keys = xzalloc(hash->n * hash->size);
|
hash->keys = xzalloc(hash->n * hash->size);
|
||||||
hash->values = xzalloc(hash->n * sizeof *hash->values);
|
hash->values = xzalloc(hash->n * sizeof(*hash->values));
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,16 +84,21 @@ void hash_insert(hash_t *hash, const void *key, const void *value) {
|
||||||
|
|
||||||
void *hash_search(const hash_t *hash, const void *key) {
|
void *hash_search(const hash_t *hash, const void *key) {
|
||||||
uint32_t i = modulo(hash_function(key, hash->size), hash->n);
|
uint32_t i = modulo(hash_function(key, hash->size), hash->n);
|
||||||
|
|
||||||
if(hash->values[i] && !memcmp(key, hash->keys + i * hash->size, hash->size)) {
|
if(hash->values[i] && !memcmp(key, hash->keys + i * hash->size, hash->size)) {
|
||||||
return (void *)hash->values[i];
|
return (void *)hash->values[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *hash_search_or_insert(hash_t *hash, const void *key, const void *value) {
|
void *hash_search_or_insert(hash_t *hash, const void *key, const void *value) {
|
||||||
uint32_t i = modulo(hash_function(key, hash->size), hash->n);
|
uint32_t i = modulo(hash_function(key, hash->size), hash->n);
|
||||||
if(hash->values[i] && !memcmp(key, hash->keys + i * hash->size, hash->size))
|
|
||||||
|
if(hash->values[i] && !memcmp(key, hash->keys + i * hash->size, hash->size)) {
|
||||||
return (void *)hash->values[i];
|
return (void *)hash->values[i];
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(hash->keys + i * hash->size, key, hash->size);
|
memcpy(hash->keys + i * hash->size, key, hash->size);
|
||||||
hash->values[i] = value;
|
hash->values[i] = value;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -101,14 +114,15 @@ void hash_delete(hash_t *hash, const void *key) {
|
||||||
/* Utility functions */
|
/* Utility functions */
|
||||||
|
|
||||||
void hash_clear(hash_t *hash) {
|
void hash_clear(hash_t *hash) {
|
||||||
memset(hash->values, 0, hash->n * sizeof *hash->values);
|
memset(hash->values, 0, hash->n * sizeof(*hash->values));
|
||||||
}
|
}
|
||||||
|
|
||||||
void hash_resize(hash_t *hash, size_t n) {
|
void hash_resize(hash_t *hash, size_t n) {
|
||||||
hash->keys = xrealloc(hash->keys, n * hash->size);
|
hash->keys = xrealloc(hash->keys, n * hash->size);
|
||||||
hash->values = xrealloc(hash->values, n * sizeof *hash->values);
|
hash->values = xrealloc(hash->values, n * sizeof(*hash->values));
|
||||||
|
|
||||||
if(n > hash->n) {
|
if(n > hash->n) {
|
||||||
memset(hash->keys + hash->n * hash->size, 0, (n - hash->n) * hash->size);
|
memset(hash->keys + hash->n * hash->size, 0, (n - hash->n) * hash->size);
|
||||||
memset(hash->values + hash->n, 0, (n - hash->n) * sizeof *hash->values);
|
memset(hash->values + hash->n, 0, (n - hash->n) * sizeof(*hash->values));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
#ifndef TINC_HASH_H
|
||||||
|
#define TINC_HASH_H
|
||||||
|
|
||||||
/*
|
/*
|
||||||
hash.h -- header file for hash.c
|
hash.h -- header file for hash.c
|
||||||
Copyright (C) 2012 Guus Sliepen <guus@tinc-vpn.org>
|
Copyright (C) 2012 Guus Sliepen <guus@tinc-vpn.org>
|
||||||
|
@ -17,9 +20,6 @@
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TINC_HASH_H__
|
|
||||||
#define __TINC_HASH_H__
|
|
||||||
|
|
||||||
typedef struct hash_t {
|
typedef struct hash_t {
|
||||||
size_t n;
|
size_t n;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
@ -39,4 +39,4 @@ extern void *hash_search_or_insert(hash_t *, const void *key, const void *value)
|
||||||
extern void hash_clear(hash_t *);
|
extern void hash_clear(hash_t *);
|
||||||
extern void hash_resize(hash_t *, size_t n);
|
extern void hash_resize(hash_t *, size_t n);
|
||||||
|
|
||||||
#endif /* __TINC_HASH_H__ */
|
#endif
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue