Import Upstream version 1.1~pre12

This commit is contained in:
Guus Sliepen 2019-08-26 13:44:52 +02:00
parent 1813f3157e
commit aa10d88732
134 changed files with 8673 additions and 4989 deletions

View file

@ -1,4 +1,4 @@
Copyright (C) 1998-2014 Ivo Timmermans, Guus Sliepen and others.
Copyright (C) 1998-2016 Ivo Timmermans, Guus Sliepen and others.
See the AUTHORS file for a complete list.
This program is free software; you can redistribute it and/or modify it under

View file

@ -1,19 +1,17 @@
The following applies to tinc:
This program is released under the GPL with the additional exemption that
compiling, linking, and/or using OpenSSL is allowed. You may provide binary
packages linked to the OpenSSL libraries, provided that all other requirements
of the GPL are met.
> This program is released under the GPL with the additional exemption that
> compiling, linking, and/or using OpenSSL is allowed. You may provide binary
> packages linked to the OpenSSL libraries, provided that all other requirements
> of the GPL are met.
The following applies to the LZO library:
Hereby I grant a special exception to the tinc VPN project
(http://tinc.nl.linux.org/) to link the LZO library with the OpenSSL library
(http://www.openssl.org).
Markus F.X.J. Oberhumer
> Hereby I grant a special exception to the tinc VPN project
> (https://www.tinc-vpn.org/) to link the LZO library with the OpenSSL library
> (https://openssl.org).
>
> Markus F.X.J. Oberhumer
When tinc is compiled with the --enable-tunemu option, the resulting binary
falls under the GPL version 3 or later.

301
ChangeLog
View file

@ -1,3 +1,304 @@
Version 1.1pre12 April 24 2016
------------------------------------------------------------------------
Guus Sliepen (166):
Allow tinc to be compiled without OpenSSL.
Add missing nolegacy/crypto.c and prf.c.
Fixes for bugs in src/Makefile.am and tincctl.c introduced by cfe9285adf391ab66faeb5def811fe08e47a221a.
Fix indentation and some whitespace issues.
Use void pointers for opaque data blobs in the SHA512 code.
Use global "now" in try_udp() and try_mtu().
Remember whether we sent our key to another node.
Try to clarify the new code in net_packet.c a bit.
Correctly estimate the initial MTU for legacy packets.
Fix size of type 2 probe replies.
Proactively send our own key when we request another node's key.
Don't send probe replies if we don't have the other's key.
Fix segfault when sptps_test cannot open the key files.
Always keep UDP mappings alive for nodes that also have a meta-connection.
Immediately send our key when a meta-connection is established.
Only send small packets during UDP probes.
Remove RTT and packet loss estimation code.
Send MTU probes only once every PingInterval.
Move detection of PMTU decrease to try_mtu().
Keep track of the largest UDP packet size received from a node.
Move UDP probe reply code into its own function.
Send the size of the largest recently received packets in type 2 probe replies.
Send gratuitous type 2 probe replies.
Improve packet source detection.
Add the "fsck" command to the CLI.
Always call res_init() before getaddrinfo().
Make "tinc add" idempotent.
Document that --force should precede commands.
Suppress warnings about parsing Ed25519 keys when they are not present.
Merge remote-tracking branch 'dechamps/sptpsabort' into 1.1
Merge remote-tracking branch 'seehuhn/1.1' into 1.1
Fix the case where we detach and use --logfile.
--syslog and --logfile are mutually exclusive.
Merge remote-tracking branch 'dechamps/staticfix' into 1.1
Merge remote-tracking branch 'dechamps/fsckwin' into 1.1
Merge remote-tracking branch 'dechamps/winmtu' into 1.1
Merge remote-tracking branch 'dechamps/windevice' into 1.1
Always call res_init() before getaddrinfo().
Merge remote-tracking branch 'dechamps/wintapver' into 1.1
Allow one-sided upgrades to Ed25519.
Fix a possible segmentation fault during key upgrades.
Don't log an error message when receiving a TERMREQ.
Fix typo 0fda572c88d02b0b200ef81d72cc4da594fa0e38 that prevented some errors from being logged.
Remove "release-" from displayed git version.
Don't include build-time generated version_git.h in the tarball.
Really remove "release-" from the git-derived version string.
Fix invitations.
Fix receiving UDP packets from tinc 1.0.x nodes.
Use AF_UNSPEC instead of AF_UNKNOWN for unspecified local address in add_edge_h().
Be more liberal accepting ADD_EDGE messages with conflicting local address information.
Try all addresses for the hostname in an invitation URL.
Let sockaddr2str() handle AF_UNSPEC addresses.
Don't send local_address in ADD_EDGE messages if it's AF_UNSPEC.
Merge remote-tracking branches 'dechamps/sptpsrestart' and 'dechamps/keychanged' into 1.1
Remove info-in-builddir option from AM_INIT_AUTOMAKE().
Fix src/Makefile.am for *BSD.
Add newline at end of precomp_data.h and sc.h.
Add source of SPTPS errors to log messages.
Don't log seqno failures in sptps_verify_datagram().
If LOCALSTATEDIR is inaccessible, store the pid and socket files in the configuration directory.
Quit with an error message if ioctl(TUNSETIFF) fails.
Add "list" as an alias for "dump" in the CLI.
Allow dumping a list of outstanding invitations.
Allocate temporary filenames on the stack.
Fix check for LOCALSTATEDIR accessibility for the CLI.
Ensure "tinc start" knows if the daemon really started succesfully.
Don't write log messages to the umbilical pipe if we don't detach.
Use socketpair() instead of pipe() for the umbilical.
Set the CLOEXEC flag on the umbilical socket.
Update copyright notices.
Fix missing return value caused by the previous commit.
Fix autoconf check for function attributes.
Fix warnings about missing return value checks.
Fix receiving SPTPS data in sptps_speed and sptps_test.
Fix alignment of output of sptps_speed.
Fix crash is sptps_logger().
Don't #include OpenSSL headers when compiling without OpenSSL.
Coalesce two if statements that check for the same thing.
Call sockaddrfree(&e->local_address) in free_edge() instead of exit_edges().
Fix undefined behaviour when left-shifting signed integers.
Remove unused code that caused warnings about an uninitialized variable.
Use AC_CONFIG_MACRO_DIRS([m4]).
Make subnet caches static.
Fix the PRF function when compiling without OpenSSL.
Use AC_CONFIG_MACRO_DIR() instead of _DIRS().
In sssp_bfs(), never try to update myself.
Add -I m4 back to ACLOCAL_AMFLAGS.
Optionally install systemd service files.
Replace bare if statements with AS_IF in configure.ac.
Fix struct node_status_t.
Fix a few memory leaks in the CLI found by AddressSanitizer.
Avoid undefined behavior.
Update THANKS file.
Don't leave dead outgoing_t's in the outgoing_list.
list_delete() already free()s the deleted element.
Add support for recvmmsg().
Use static buffers for recvmmsg(), initialize them only as needed.
Only add a reflexive address when we're sure it's working.
Merge remote-tracking branch 'mweinelt/tinc-gui' into 1.1
Add the ability to sign and verify files.
Update .gitignore.
Only check for -fno-strict-overflow if -fwrapv does not work.
Use nostdinc instead of overriding DEFAULT_INCLUDES.
Improve performance of edge updates.
Fix forwarding of edge updates.
Clarify that scripts are called synchronously.
Small fixes for the documentation.
Add warnings for bad combinations of Device and Interface.
Fix for botched cherry-pick commit 60fb230.
Fix typo.
Don't compile getopt*.c if the system provides getopt_long().
Update .gitignore.
Update THANKS.
Use iface instead of interface.
Support ToS/DiffServ for IPv6 meta and UDP connections.
Fix --logfile without a filename on Windows.
Never call putenv() with data on the stack.
Update "now" after connect() when making outgoing connections.
Update support for BSD tun/tap devices, add support for OS X utun interfaces.
Explicitly mention that LibreSSL can be used as well.
Update links in the documentation.
Enable silent builds by default.
Really don't compile getopt*.c if the system provides getopt_long().
Remove elliptic curve stubs from gcrypt/, add PRF implementation.
Update .gitignore.
Make text files Markdown-compatible.
Remove checks for headers and functions that are in C99.
Fix compiling under MinGW.
Replace usleep() with nanosleep().
Use getcwd() instead of get_current_dir_name().
Fix typo in Makefile.am.
Fix version_get.h generation on BSD.
Remove checks for non-C99 compliant compilers.
Remove support for Windows 2000 and anything that doesn't support getaddrinfo().
Make some platform-specific header checks conditional.
Add version_git.h and sample-config.tar.gz to CLEANFILES.
Don't assume sa.sa_family is a short int.
Remove use of strcpy() and sprintf().
Don't use HAVE_SYSTEM, the autoconf check was removed.
Fix a non-working cast to get rid of a compiler warning.
Fix generation of version_git.h for some versions of BSD make.
Fix some compiler warnings from MinGW.
Fix conditional checking of tun/tap headers on DragonFly BSD.
Fix crash at startup when Device is not specified on OS X.
Stop using SOL_TCP, SOL_IP and SOL_IPV6.
Document how invitation files work.
Generate a tinc-up script from an invitation.
Move some stray #includes.
Allow gateways to be specified for routes.
Fix gateway parsing in invitation files.
Fix compiler warnings.
Add a test for tinc-up creation from invitations.
Chdir() to the configuration directory instead of /.
Use ifconfig_header().
Add stricter checks for netnames.
Handle special characters in sptps_test only if the --special option is given.
Don't call terminate_connection(myself->connection).
Speed up AutoConnect at startup.
Fix the "network" command in tinc shell.
Move documentation of invitations to the manual.
Have "tinc fsck" recognize Ed25519PublicKey statements.
Fix possible read of freed memory when verifying the signature of a file.
Fix a compiler warning on Windows.
Fix starting tinc as a service on Windows.
Don't check file permissions on Windows during fsck.
Releasing 1.1pre12.
Etienne Dechamps (72):
Clarify the send_mtu_probe() function.
Add the try_tx() function.
Move try_sptps() closer to try_tx().
Add UDP discovery mechanism.
Move responsibility for local discovery to UDP discovery.
Remove PMTU discovery code redundant with UDP discovery.
Move PMTU discovery code into the TX path.
Move try_mtu() closer to try_tx().
Fix MTU as soon as possible.
Use -1 to identify the post-initial MTU discovery state.
Send one MTU probe at a time.
Remove bandwidth estimation code.
Use a smarter algorithm for choosing MTU discovery probe sizes.
Adjust MTU probe counts.
Don't send MTU probes smaller than 512 bytes.
Add IP_MTU-based maxmtu estimation.
Fine-tune the MTU discovery multiplier for the maxmtu < MTU case.
Recalculate and resend MTU probes if they are too large for the system.
Use a different UDP discovery interval if the tunnel is established.
Fix typo in logging statement.
Fix dynamic UDP SPTPS relaying.
Fix UDP/MTU discovery in intermediate SPTPS UDP relays.
Don't abort() willy-nilly in SPTPS code.
Add UDP_INFO protocol message.
Add MTU_INFO protocol message.
Throttle the rate of UDP_INFO messages.
Throttle the rate of MTU_INFO messages.
Don't send UDP probes past static relays.
Fix invalid getuid() call on Windows.
Fix HAVE_DECL_RES_INIT conditionals.
Make sure packet header structures are correctly packed on Windows.
When disabling the Windows device, wait for pending reads to complete.
Fix Windows device asynchronous write behavior.
Set the default for UDPRcvBuf and UDPSndBuf to 1M.
Increase the ReplayWindow default from 16 to 32.
Log TAP-Windows driver version on startup.
Warn about performance if using TAP-Windows >=9.21.
Use git description as the tinc version.
Use git describe to populate autoconf's VERSION.
Remove explicit distribution rules for m4 scripts.
Add support for out-of-tree ("VPATH") builds.
When relaying, send probes to the destination, not the source.
Use the correct originator node when relaying SPTPS UDP packets.
Expose the raw SPTPS send interface from net_packet.
Try to use UDP to relay SPTPS packets received over TCP.
Rename REQ_SPTPS to SPTPS_PACKET.
Only read one record at a time in sptps_receive_data().
Introduce raw TCP SPTPS packet transport.
Prevent SPTPS key regeneration packets from entering an UDP relay path.
Trivial: make sptps_receive_data_datagram() a little more readable.
Proactively restart the SPTPS tunnel if we get receive errors.
Don't send KEY_CHANGED messages if we don't support the legacy protocol.
Make sure the MIN() macro is defined.
Don't pollute the system header directory namespace.
Fix SPTPS condition in try_harder().
Don't parse node IDs if the sending node doesn't support them.
Fix direct UDP communciation with pre-relaying 1.1 nodes.
Fix crashes when trying unreachable nodes.
Don't set up an ongoing connection to myself.
Fix wrong format string type in send_sptps_tcppacket().
Fix invalid pointer use in get_my_hostname().
Don't try to relay packets to unreachable nodes.
Protect against callbacks removing items from the io tree.
Use a splay tree for node UDP addresses in order to avoid collisions.
Revert "Cache node IDs in a hash table for faster lookups."
Make sure the packet source MAC address is always set.
Add a new optional dependency on the miniupnpc library.
Add UPnP support to tincd.
Allow tinc to be built with miniupnpc on Windows.
Try to ensure we build correctly against various libminiupnpc versions.
Don't unset validkey when receiving SPTPS handshakes over ANS_KEY.
Add upnp.h to tincd SOURCES.
thorkill (8):
Fixed 2 leaks in setup_myself()
Cleanup edges stored in edge_weight_tree on exit
Cleanup local_address in protocol_edge.c
Removed double break;
Included missing names.h
Make sure we do not allocate new edge when talking to old nodes and the same edge already exists
Prevent tinc from forgeting e->local_address
Do not access e->to->prevedge if not defined
Vittorio Gambaletta (VittGam) (6):
Fix DecrementTTL option.
Fix source IP address for ICMP unreachable packets generated by tinc.
Try to reply with node address only when decrementing the TTL.
Fix DecrementTTL option for packets destined to the local node.
s/broadcast_packet_helper/route_broadcast/
Remove forward declaration for do_decrement_ttl.
Martin Weinelt (5):
tinc-gui: Reformat codebase according to PEP8
tinc-gui: Update Node object to correctly parse responses
tinc-gui: Fix GetListCtrl method name in SuperListCtrl
tinc-gui: Use ArgumentParser, default to python2
tinc-gui: Properly initialize class attributes for VPN in __init__
Sven-Haegar Koch (3):
Fixed variables.test testsuite after 'Make "tinc add" idempotent.' change.
Let sockaddr2hostname() handle AF_UNSPEC addresses.
Fix check for public key in invite-join.test.
Florian Klink (2):
(read|append)_config_file: log open errors as LOG_DEBUG
setup_outgoing_connection: log to LOG_DEBUG on if no known address
LunarShaddow (2):
fix typo
re-arrange include sequence to avoid a mingw introduced bug.
Dato Simó (1):
Fix typo in tinc.texi.
Jo-Philipp Wich (1):
fix musl compatibility
Jochen Voss (1):
Add a new --syslog option for tincd.
Nathan Stratton Treadway (1):
Fix invalid checksum generation.
Pierre Emeriaud (1):
Fix typo in tincctl help.
xentec (1):
Fix compile errors introduced in cfe9285adf391ab66faeb5def811fe08e47a221a
Version 1.1pre11 December 27 2014
------------------------------------------------------------------------

View file

@ -2,14 +2,22 @@
AUTOMAKE_OPTIONS = gnu
SUBDIRS = m4 src doc gui test
SUBDIRS = src doc gui test systemd
ACLOCAL_AMFLAGS = -I m4
EXTRA_DIST = COPYING.README README.android
# If git describe works, force autoconf to run in order to make sure we have the
# current version number from git in the resulting configure script.
configure-version:
-cd $(srcdir) && git describe && autoconf --force
# Triggering the README target means we are building a distribution (make dist).
README: configure-version
ChangeLog:
git log > ChangeLog
(cd $(srcdir) && git log) > ChangeLog
deb:
dpkg-buildpackage -rfakeroot
@ -23,5 +31,5 @@ release:
rm -f ChangeLog
$(MAKE) ChangeLog
echo "Please edit the NEWS file now..."
/usr/bin/editor NEWS
/usr/bin/editor $(srcdir)/NEWS
$(MAKE) dist

View file

@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.14.1 from Makefile.am.
# Makefile.in generated by automake 1.15 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# Copyright (C) 1994-2014 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -14,7 +14,17 @@
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
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 \
?) ;; \
@ -78,21 +88,18 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = .
DIST_COMMON = INSTALL NEWS README AUTHORS ChangeLog \
$(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/configure $(am__configure_deps) \
$(srcdir)/config.h.in COPYING THANKS compile config.guess \
config.sub depcomp install-sh missing
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
$(top_srcdir)/m4/ax_check_link_flag.m4 \
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \
$(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \
$(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \
$(top_srcdir)/configure.ac
$(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 $(top_srcdir)/configure \
$(am__configure_deps) $(am__DIST_COMMON)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno config.status.lineno
mkinstalldirs = $(install_sh) -d
@ -156,6 +163,9 @@ ETAGS = etags
CTAGS = ctags
CSCOPE = cscope
DIST_SUBDIRS = $(SUBDIRS)
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in AUTHORS \
COPYING ChangeLog INSTALL NEWS README THANKS compile \
config.guess config.sub depcomp install-sh missing
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
@ -231,6 +241,7 @@ LIBS = @LIBS@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MINIUPNPC_LIBS = @MINIUPNPC_LIBS@
MKDIR_P = @MKDIR_P@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
@ -288,16 +299,18 @@ 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@
AUTOMAKE_OPTIONS = gnu
SUBDIRS = m4 src doc gui test
SUBDIRS = src doc gui test systemd
ACLOCAL_AMFLAGS = -I m4
EXTRA_DIST = COPYING.README README.android
all: config.h
@ -319,7 +332,6 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@ -461,12 +473,6 @@ distclean-tags:
-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
distdir: $(DISTFILES)
@case `sed 15q $(srcdir)/NEWS` in \
*"$(VERSION)"*) : ;; \
*) \
echo "NEWS not updated; not releasing" 1>&2; \
exit 1;; \
esac
$(am__remove_distdir)
test -d "$(distdir)" || mkdir "$(distdir)"
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
@ -547,15 +553,15 @@ dist-xz: distdir
$(am__post_remove_distdir)
dist-tarZ: distdir
@echo WARNING: "Support for shar distribution archives is" \
"deprecated." >&2
@echo WARNING: "Support for distribution archives compressed with" \
"legacy program 'compress' is deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
$(am__post_remove_distdir)
dist-shar: distdir
@echo WARNING: "Support for distribution archives compressed with" \
"legacy program 'compress' is deprecated." >&2
@echo WARNING: "Support for shar distribution archives is" \
"deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
$(am__post_remove_distdir)
@ -591,17 +597,17 @@ distcheck: dist
esac
chmod -R a-w $(distdir)
chmod u+w $(distdir)
mkdir $(distdir)/_build $(distdir)/_inst
mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
chmod a-w $(distdir)
test -d $(distdir)/_build || exit 0; \
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& am__cwd=`pwd` \
&& $(am__cd) $(distdir)/_build \
&& ../configure \
&& $(am__cd) $(distdir)/_build/sub \
&& ../../configure \
$(AM_DISTCHECK_CONFIGURE_FLAGS) \
$(DISTCHECK_CONFIGURE_FLAGS) \
--srcdir=.. --prefix="$$dc_install_base" \
--srcdir=../.. --prefix="$$dc_install_base" \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
@ -776,9 +782,19 @@ uninstall-am:
mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \
uninstall-am
.PRECIOUS: Makefile
# If git describe works, force autoconf to run in order to make sure we have the
# current version number from git in the resulting configure script.
configure-version:
-cd $(srcdir) && git describe && autoconf --force
# Triggering the README target means we are building a distribution (make dist).
README: configure-version
ChangeLog:
git log > ChangeLog
(cd $(srcdir) && git log) > ChangeLog
deb:
dpkg-buildpackage -rfakeroot
@ -792,7 +808,7 @@ release:
rm -f ChangeLog
$(MAKE) ChangeLog
echo "Please edit the NEWS file now..."
/usr/bin/editor NEWS
/usr/bin/editor $(srcdir)/NEWS
$(MAKE) dist
# Tell versions [3.59,3.63) of GNU make to not export all variables.

901
NEWS

File diff suppressed because it is too large Load diff

36
README
View file

@ -1,11 +1,7 @@
This is the README file for tinc version 1.1pre11. Installation
This is the README file for tinc version 1.1pre12. Installation
instructions may be found in the INSTALL file.
tinc is Copyright (C) 1998-2014 by:
Ivo Timmermans,
Guus Sliepen <guus@tinc-vpn.org>,
and others.
tinc is Copyright © 1998-2016 Ivo Timmermans, Guus Sliepen <guus@tinc-vpn.org>, and others.
For a complete list of authors see the AUTHORS file.
@ -36,11 +32,12 @@ at your own risk.
Compatibility
-------------
Version 1.1pre11 is compatible with 1.0pre8, 1.0 and later, but not with older
Version 1.1pre12 is compatible with 1.0pre8, 1.0 and later, but not with older
versions of tinc.
When the ExperimentalProtocol option is used, tinc is still compatible with
1.0.X and 1.1pre11 itself, but not with any other 1.1preX version.
1.0.X, 1.1pre11 and later, but not with any version between 1.1pre1 and
1.1pre10.
Requirements
@ -49,15 +46,14 @@ Requirements
In order to compile tinc, you will need a GNU C compiler environment. Please
ensure you have the latest stable versions of all the required libraries:
- OpenSSL (http://www.openssl.org/) version 1.0.0 or later, with support for
elliptic curve cryptography (ECC) and Galois counter mode (GCM) enabled.
- LibreSSL (http://www.libressl.org/) or OpenSSL (https://openssl.org/) version 1.0.0 or later.
The following libraries are used by default, but can be disabled if necessary:
- zlib (http://www.gzip.org/zlib/)
- lzo (http://www.oberhumer.com/opensource/lzo/)
- zlib (http://www.zlib.net/)
- LZO (https://www.oberhumer.com/opensource/lzo/)
- ncurses (http://invisible-island.net/ncurses/)
- readline (ftp://ftp.gnu.org/pub/gnu/readline/)
- readline (https://cnswww.cns.cwru.edu/php/chet/readline/rltop.html)
Features
@ -70,12 +66,12 @@ those nodes, tinc will learn about all other nodes on the VPN, and will make
connections automatically. When direct connections are not possible, data will
be forwarded by intermediate nodes.
By default, nodes authenticate each other using 2048 bit RSA (or 521 bit
ECDSA*) keys. Traffic is encrypted using Blowfish in CBC mode (or AES-256 in
GCM mode*), authenticated using HMAC-SHA1 (or GCM*), and is protected against
replay attacks.
*) When using the ExperimentalProtocol option.
Tinc 1.1 support two protocols. The first is a legacy protocol that provides
backwards compatibility with tinc 1.0 nodes, and which by default uses 2048 bit
RSA keys for authentication, and encrypts traffic using Blowfish in CBC mode
and HMAC-SHA1. The second is a new protocol which uses Curve25519 keys for
authentication, and encrypts traffic using Chacha20-Poly1305, and provides
forward secrecy.
Tinc fully supports IPv6.
@ -85,7 +81,7 @@ modes, "switch" and "hub", let the tinc daemons work together to form a virtual
Ethernet network switch or hub.
Normally, when started tinc will detach and run in the background. In a native
Windows environment this means tinc will intall itself as a service, which will
Windows environment this means tinc will install itself as a service, which will
restart after reboots. To prevent tinc from detaching or running as a service,
use the -D option.

View file

@ -1,20 +1,23 @@
Quick how-o cross compile tinc for android (done from $HOME/android/):
Quick how-to cross compile tinc for Android (done from $HOME/android/):
- Download android NDK and setup local ARM toolchain:
wget http://dl.google.com/android/ndk/android-ndk-r8b-linux-x86.tar.bz2
tar xfj android-ndk-r8b-linux-x86.tar.bz2
./android-ndk-r8b/build/tools/make-standalone-toolchain.sh --platform=android-5 --install-dir=/tmp/my-android-toolchain
- Download Android NDK and setup local ARM toolchain:
- Download and cross-compile openSSL for ARM:
wget http://www.openssl.org/source/openssl-1.0.1c.tar.gz
tar xfz openssl-1.0.1c.tar.gz
cd openssl-1.0.1c
./Configure dist
make CC=/tmp/my-android-toolchain/bin/arm-linux-androideabi-gcc AR="/tmp/my-android-toolchain/bin/arm-linux-androideabi-ar r" RANLIB=/tmp/my-android-toolchain/bin/arm-linux-androideabi-ranlib
wget http://dl.google.com/android/ndk/android-ndk-r8b-linux-x86.tar.bz2
tar xfj android-ndk-r8b-linux-x86.tar.bz2
./android-ndk-r8b/build/tools/make-standalone-toolchain.sh --platform=android-5 --install-dir=/tmp/my-android-toolchain
- Download and cross-compile OpenSSL for ARM:
wget http://www.openssl.org/source/openssl-1.0.1c.tar.gz
tar xfz openssl-1.0.1c.tar.gz
cd openssl-1.0.1c
./Configure dist
make CC=/tmp/my-android-toolchain/bin/arm-linux-androideabi-gcc AR="/tmp/my-android-toolchain/bin/arm-linux-androideabi-ar r" RANLIB=/tmp/my-android-toolchain/bin/arm-linux-androideabi-ranlib
- Clone and cross-compile tinc:
git clone git://tinc-vpn.org/tinc
cd tinc
autoreconf -fsi
CC=/tmp/my-android-toolchain/bin/arm-linux-androideabi-gcc ./configure --host=arm-linux --disable-lzo --with-openssl-lib=$HOME/android/openssl-1.0.1c --with-openssl-include=$HOME/android/openssl-1.0.1c/include/
make -j5
git clone git://tinc-vpn.org/tinc
cd tinc
autoreconf -fsi
CC=/tmp/my-android-toolchain/bin/arm-linux-androideabi-gcc ./configure --host=arm-linux --disable-lzo --with-openssl-lib=$HOME/android/openssl-1.0.1c --with-openssl-include=$HOME/android/openssl-1.0.1c/include/
make -j5

26
THANKS
View file

@ -14,6 +14,7 @@ We would like to thank the following people for their contributions to tinc:
* Cheng LI
* Cris van Pelt
* Darius Jahandarie
* Dato Simó
* David Pflug
* Delf Eldkraft
* Dennis Joachimsthaler
@ -22,11 +23,14 @@ We would like to thank the following people for their contributions to tinc:
* Erik Tews
* Etienne Dechamps
* Florent Clairambault
* Florian Klink
* Florian Weik
* Flynn Marquardt
* Franz Pletz
* Gary Kessler and Claudia Gonzalez
* Grzegorz Dymarek
* Hans Bayle
* Harvest
* Ivo van Dong
* James Cook
* James MacLean
@ -34,14 +38,17 @@ We would like to thank the following people for their contributions to tinc:
* Jason Harper
* Jason Livesay
* Jelle de Jong
* Jeroen Domburg
* Jeroen Ubbink
* Jerome Etienne
* Jo-Philipp Wich
* Jochen Voss
* Julien Muchembled
* Lavrans Laading
* Loïc Dachary
* Loïc Grenié
* Lubomír Bulej
* LunarShaddow
* Mads Kiilerich
* Marc A. Lehmann
* Mark Glines
@ -50,36 +57,51 @@ We would like to thank the following people for their contributions to tinc:
* Martin Kihlgren
* Martin Schobert
* Martin Schürrer
* Martin Weinelt
* Matias Carrasco
* Max Rijevski
* Menno Smits
* Mesar Hameed
* Michael Tokarev
* Miles Nordin
* Nathan Stratton Treadway
* Murat Donmez
* Nick Hibma
* Nick Patavalis
* Paul Littlefield
* Philipp Babel
* Pierre Emeriaud
* Rafał Leśniak
* Rhosyn Celyn
* Robert van der Meulen
* Rumko
* Sam Bryan
* Samuel Thibault
* Saverio Proto
* Scott Lamb
* Steffan Karger
* Stig Fagrell
* Sven-Haegar Koch
* Teemu Kiviniemi
* Thomas Tsiakalakis
* thorkill
* Timothy Redaelli
* Tomasz Fortuna
* Tomislav Čohar
* Tommy Arnkværn
* Tonnerre Lombard
* Ulrich Seifert
* Vil Brekin
* Vittorio Gambaletta
* Wessel Dankers
* William A. Kennington III
* William McArthur
* Wouter van Heyst
* xentec
* 戴 鸣
And everyone we forgot (if we did, please let us know). Thank you!
Ivo Timmermans
Guus Sliepen
---
Ivo Timmermans,
Guus Sliepen.

56
aclocal.m4 vendored
View file

@ -1,6 +1,6 @@
# generated automatically by aclocal 1.14.1 -*- Autoconf -*-
# generated automatically by aclocal 1.15 -*- Autoconf -*-
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -20,7 +20,7 @@ You have another version of autoconf. It may work, but is not guaranteed to.
If you have problems, you may need to regenerate the build system entirely.
To do so, use the procedure documented by the package, typically 'autoreconf'.])])
# Copyright (C) 2002-2013 Free Software Foundation, Inc.
# Copyright (C) 2002-2014 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -32,10 +32,10 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.])
# generated from the m4 files accompanying Automake X.Y.
# (This private macro should not be called outside this file.)
AC_DEFUN([AM_AUTOMAKE_VERSION],
[am__api_version='1.14'
[am__api_version='1.15'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
m4_if([$1], [1.14.1], [],
m4_if([$1], [1.15], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
@ -51,14 +51,14 @@ m4_define([_AM_AUTOCONF_VERSION], [])
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
[AM_AUTOMAKE_VERSION([1.14.1])dnl
[AM_AUTOMAKE_VERSION([1.15])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
# Copyright (C) 2001-2013 Free Software Foundation, Inc.
# Copyright (C) 2001-2014 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -110,7 +110,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd`
# AM_CONDITIONAL -*- Autoconf -*-
# Copyright (C) 1997-2013 Free Software Foundation, Inc.
# Copyright (C) 1997-2014 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -141,7 +141,7 @@ AC_CONFIG_COMMANDS_PRE(
Usually this means the macro was only invoked conditionally.]])
fi])])
# Copyright (C) 1999-2013 Free Software Foundation, Inc.
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -332,7 +332,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
# Generate code to set up dependency tracking. -*- Autoconf -*-
# Copyright (C) 1999-2013 Free Software Foundation, Inc.
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -408,7 +408,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
# Do all the work for Automake. -*- Autoconf -*-
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -498,8 +498,8 @@ AC_REQUIRE([AC_PROG_MKDIR_P])dnl
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
# We need awk for the "check" target. The system "awk" is bad on
# some platforms.
# We need awk for the "check" target (and possibly the TAP driver). The
# system "awk" is bad on some platforms.
AC_REQUIRE([AC_PROG_AWK])dnl
AC_REQUIRE([AC_PROG_MAKE_SET])dnl
AC_REQUIRE([AM_SET_LEADING_DOT])dnl
@ -573,6 +573,9 @@ END
AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
fi
fi
dnl The trailing newline in this macro's definition is deliberate, for
dnl backward compatibility and to allow trailing 'dnl'-style comments
dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841.
])
dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
@ -602,7 +605,7 @@ for _am_header in $config_headers :; do
done
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
# Copyright (C) 2001-2013 Free Software Foundation, Inc.
# Copyright (C) 2001-2014 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -613,7 +616,7 @@ echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_co
# Define $install_sh.
AC_DEFUN([AM_PROG_INSTALL_SH],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
if test x"${install_sh}" != xset; then
if test x"${install_sh+set}" != xset; then
case $am_aux_dir in
*\ * | *\ *)
install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
@ -623,7 +626,7 @@ if test x"${install_sh}" != xset; then
fi
AC_SUBST([install_sh])])
# Copyright (C) 2003-2013 Free Software Foundation, Inc.
# Copyright (C) 2003-2014 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -644,7 +647,7 @@ AC_SUBST([am__leading_dot])])
# Check to see how 'make' treats includes. -*- Autoconf -*-
# Copyright (C) 2001-2013 Free Software Foundation, Inc.
# Copyright (C) 2001-2014 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -694,7 +697,7 @@ rm -f confinc confmf
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
# Copyright (C) 1997-2013 Free Software Foundation, Inc.
# Copyright (C) 1997-2014 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -733,7 +736,7 @@ fi
# Helper functions for option handling. -*- Autoconf -*-
# Copyright (C) 2001-2013 Free Software Foundation, Inc.
# Copyright (C) 2001-2014 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -762,7 +765,7 @@ AC_DEFUN([_AM_SET_OPTIONS],
AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
# Copyright (C) 1999-2013 Free Software Foundation, Inc.
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -809,7 +812,7 @@ AC_LANG_POP([C])])
# For backward compatibility.
AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
# Copyright (C) 2001-2013 Free Software Foundation, Inc.
# Copyright (C) 2001-2014 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -828,7 +831,7 @@ AC_DEFUN([AM_RUN_LOG],
# Check to make sure that the build environment is sane. -*- Autoconf -*-
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -909,7 +912,7 @@ AC_CONFIG_COMMANDS_PRE(
rm -f conftest.file
])
# Copyright (C) 2009-2013 Free Software Foundation, Inc.
# Copyright (C) 2009-2014 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -969,7 +972,7 @@ AC_SUBST([AM_BACKSLASH])dnl
_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
])
# Copyright (C) 2001-2013 Free Software Foundation, Inc.
# Copyright (C) 2001-2014 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -997,7 +1000,7 @@ fi
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])
# Copyright (C) 2006-2013 Free Software Foundation, Inc.
# Copyright (C) 2006-2014 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -1016,7 +1019,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# Check how to create a tarball. -*- Autoconf -*-
# Copyright (C) 2004-2013 Free Software Foundation, Inc.
# Copyright (C) 2004-2014 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -1153,6 +1156,7 @@ m4_include([m4/ax_check_link_flag.m4])
m4_include([m4/curses.m4])
m4_include([m4/libgcrypt.m4])
m4_include([m4/lzo.m4])
m4_include([m4/miniupnpc.m4])
m4_include([m4/openssl.m4])
m4_include([m4/readline.m4])
m4_include([m4/zlib.m4])

View file

@ -3,7 +3,7 @@
scriptversion=2012-10-14.11; # UTC
# Copyright (C) 1999-2013 Free Software Foundation, Inc.
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify

47
config.guess vendored
View file

@ -1,8 +1,8 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright 1992-2014 Free Software Foundation, Inc.
# Copyright 1992-2015 Free Software Foundation, Inc.
timestamp='2014-03-23'
timestamp='2015-08-20'
# 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
@ -24,12 +24,12 @@ timestamp='2014-03-23'
# program. This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3").
#
# Originally written by Per Bothner.
# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
#
# You can get the latest version of this script from:
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
#
# Please send patches with a ChangeLog entry to config-patches@gnu.org.
# Please send patches to <config-patches@gnu.org>.
me=`echo "$0" | sed -e 's,.*/,,'`
@ -50,7 +50,7 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
Copyright 1992-2014 Free Software Foundation, Inc.
Copyright 1992-2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@ -168,20 +168,27 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# Note: NetBSD doesn't particularly care about the vendor
# portion of the name. We always set it to "unknown".
sysctl="sysctl -n hw.machine_arch"
UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
/usr/sbin/$sysctl 2>/dev/null || echo unknown)`
UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
/sbin/$sysctl 2>/dev/null || \
/usr/sbin/$sysctl 2>/dev/null || \
echo unknown)`
case "${UNAME_MACHINE_ARCH}" in
armeb) machine=armeb-unknown ;;
arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;;
sh5el) machine=sh5le-unknown ;;
earmv*)
arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'`
machine=${arch}${endian}-unknown
;;
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
esac
# The Operating System including object format, if it has switched
# to ELF recently, or will in the future.
case "${UNAME_MACHINE_ARCH}" in
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax)
eval $set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ELF__
@ -197,6 +204,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
os=netbsd
;;
esac
# Determine ABI tags.
case "${UNAME_MACHINE_ARCH}" in
earm*)
expr='s/^earmv[0-9]/-eabi/;s/eb$//'
abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"`
;;
esac
# The OS release
# Debian GNU/NetBSD machines have a different userland, and
# thus, need a distinct triplet. However, they do not need
@ -207,13 +221,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
release='-gnu'
;;
*)
release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2`
;;
esac
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
# contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
echo "${machine}-${os}${release}"
echo "${machine}-${os}${release}${abi}"
exit ;;
*:Bitrig:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
@ -235,6 +249,9 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:MirBSD:*:*)
echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
exit ;;
*:Sortix:*:*)
echo ${UNAME_MACHINE}-unknown-sortix
exit ;;
alpha:OSF1:*:*)
case $UNAME_RELEASE in
*4.0)
@ -579,8 +596,9 @@ EOF
else
IBM_ARCH=powerpc
fi
if [ -x /usr/bin/oslevel ] ; then
IBM_REV=`/usr/bin/oslevel`
if [ -x /usr/bin/lslpp ] ; then
IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
else
IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
fi
@ -932,6 +950,9 @@ EOF
crisv32:Linux:*:*)
echo ${UNAME_MACHINE}-axis-linux-${LIBC}
exit ;;
e2k:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
frv:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
@ -1020,7 +1041,7 @@ EOF
echo ${UNAME_MACHINE}-dec-linux-${LIBC}
exit ;;
x86_64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
echo ${UNAME_MACHINE}-pc-linux-${LIBC}
exit ;;
xtensa*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}

View file

@ -1,5 +1,8 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* Disable support for the legacy (tinc 1.0) protocol */
#undef DISABLE_LEGACY
/* Support for jumbograms (packets up to 9000 bytes) */
#undef ENABLE_JUMBOGRAMS
@ -36,22 +39,6 @@
/* Darwin (MacOS/X) */
#undef HAVE_DARWIN
/* Define to 1 if you have the declaration of `freeaddrinfo', and to 0 if you
don't. */
#undef HAVE_DECL_FREEADDRINFO
/* Define to 1 if you have the declaration of `gai_strerror', and to 0 if you
don't. */
#undef HAVE_DECL_GAI_STRERROR
/* Define to 1 if you have the declaration of `getaddrinfo', and to 0 if you
don't. */
#undef HAVE_DECL_GETADDRINFO
/* Define to 1 if you have the declaration of `getnameinfo', and to 0 if you
don't. */
#undef HAVE_DECL_GETNAMEINFO
/* 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
@ -60,6 +47,9 @@
don't. */
#undef HAVE_DECL_RES_INIT
/* Define to 1 if you have the `devname' function. */
#undef HAVE_DEVNAME
/* Define to 1 if you have the <dirent.h> header file. */
#undef HAVE_DIRENT_H
@ -72,6 +62,9 @@
/* Define to 1 if you have the `fchmod' function. */
#undef HAVE_FCHMOD
/* Define to 1 if you have the `fdevname' function. */
#undef HAVE_FDEVNAME
/* Define to 1 if you have the `flock' function. */
#undef HAVE_FLOCK
@ -87,18 +80,18 @@
/* Define to 1 if you have the <gcrypt.h> header file. */
#undef HAVE_GCRYPT_H
/* Define to 1 if you have the <getopt.h> header file. */
#undef HAVE_GETOPT_H
/* getopt_long() */
#undef HAVE_GETOPT_LONG
/* Define to 1 if you have the `gettimeofday' function. */
#undef HAVE_GETTIMEOFDAY
/* Define to 1 if you have the `get_current_dir_name' function. */
#undef HAVE_GET_CURRENT_DIR_NAME
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the `nsl' library (-lnsl). */
#undef HAVE_LIBNSL
/* Define to 1 if you have the `resolv' library (-lresolv). */
#undef HAVE_LIBRESOLV
@ -132,9 +125,18 @@
/* MinGW */
#undef HAVE_MINGW
/* have miniupnpc support */
#undef HAVE_MINIUPNPC
/* Define to 1 if you have the <miniupnpc/miniupnpc.h> header file. */
#undef HAVE_MINIUPNPC_MINIUPNPC_H
/* Define to 1 if you have the `mlockall' function. */
#undef HAVE_MLOCKALL
/* Define to 1 if you have the `nanosleep' function. */
#undef HAVE_NANOSLEEP
/* NetBSD */
#undef HAVE_NETBSD
@ -189,6 +191,9 @@
/* Define to 1 if you have the <net/if_types.h> header file. */
#undef HAVE_NET_IF_TYPES_H
/* Define to 1 if you have the <net/if_utun.h> header file. */
#undef HAVE_NET_IF_UTUN_H
/* Define to 1 if you have the <net/tap/if_tap.h> header file. */
#undef HAVE_NET_TAP_IF_TAP_H
@ -222,9 +227,6 @@
/* Define to 1 if you have the `putenv' function. */
#undef HAVE_PUTENV
/* Define to 1 if you have the `random' function. */
#undef HAVE_RANDOM
/* Define to 1 if you have the `RAND_status' function. */
#undef HAVE_RAND_STATUS
@ -237,33 +239,21 @@
/* Define to 1 if you have the <readline/readline.h> header file. */
#undef HAVE_READLINE_READLINE_H
/* Define to 1 if you have the `recvmmsg' function. */
#undef HAVE_RECVMMSG
/* Define to 1 if you have the <resolv.h> header file. */
#undef HAVE_RESOLV_H
/* Define to 1 if you have the `select' function. */
#undef HAVE_SELECT
/* Define to 1 if the system has the type `socklen_t'. */
#undef HAVE_SOCKLEN_T
/* Solaris/SunOS */
#undef HAVE_SOLARIS
/* Define to 1 if you have the <stdbool.h> header file. */
#undef HAVE_STDBOOL_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the `strdup' function. */
#undef HAVE_STRDUP
/* Define to 1 if you have the `strerror' function. */
#undef HAVE_STRERROR
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
@ -273,12 +263,6 @@
/* Define to 1 if you have the `strsignal' function. */
#undef HAVE_STRSIGNAL
/* Define to 1 if you have the `strtol' function. */
#undef HAVE_STRTOL
/* Define to 1 if the system has the type `struct addrinfo'. */
#undef HAVE_STRUCT_ADDRINFO
/* Define to 1 if the system has the type `struct arphdr'. */
#undef HAVE_STRUCT_ARPHDR
@ -294,12 +278,6 @@
/* Define to 1 if the system has the type `struct icmp6_hdr'. */
#undef HAVE_STRUCT_ICMP6_HDR
/* Define to 1 if the system has the type `struct in6_addr'. */
#undef HAVE_STRUCT_IN6_ADDR
/* Define to 1 if the system has the type `struct in_addr'. */
#undef HAVE_STRUCT_IN_ADDR
/* Define to 1 if the system has the type `struct ip'. */
#undef HAVE_STRUCT_IP
@ -312,15 +290,9 @@
/* Define to 1 if the system has the type `struct nd_opt_hdr'. */
#undef HAVE_STRUCT_ND_OPT_HDR
/* Define to 1 if the system has the type `struct sockaddr_in6'. */
#undef HAVE_STRUCT_SOCKADDR_IN6
/* Define to 1 if you have the <syslog.h> header file. */
#undef HAVE_SYSLOG_H
/* Define to 1 if you have the `system' function. */
#undef HAVE_SYSTEM
/* Define to 1 if you have the <sys/file.h> header file. */
#undef HAVE_SYS_FILE_H
@ -348,36 +320,21 @@
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <sys/uio.h> header file. */
#undef HAVE_SYS_UIO_H
/* Define to 1 if you have the <sys/un.h> header file. */
#undef HAVE_SYS_UN_H
/* Define to 1 if you have the <sys/wait.h> header file. */
#undef HAVE_SYS_WAIT_H
/* Define to 1 if you have the `time' function. */
#undef HAVE_TIME
/* Define to 1 if you have the <time.h> header file. */
#undef HAVE_TIME_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the `unsetenv' function. */
#undef HAVE_UNSETENV
/* Define to 1 if you have the `usleep' function. */
#undef HAVE_USLEEP
/* Define to 1 if you have the `vsyslog' function. */
#undef HAVE_VSYSLOG
/* Define to 1 if you have the `writev' function. */
#undef HAVE_WRITEV
/* have zlib compression support */
#undef HAVE_ZLIB
@ -414,12 +371,6 @@
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#undef TIME_WITH_SYS_TIME
/* Define to 1 if your <sys/time.h> declares `struct tm'. */
#undef TM_IN_SYS_TIME
/* Enable extensions on AIX 3, Interix. */
#ifndef _ALL_SOURCE
# undef _ALL_SOURCE
@ -445,9 +396,6 @@
/* Version number of package */
#undef VERSION
/* Compile with support for Windows 2000 */
#undef WITH_WINDOWS2000
/* Define to 1 if on MINIX. */
#undef _MINIX
@ -466,16 +414,3 @@
/* Defined if the __warn_unused_result__ attribute is not supported. */
#undef __warn_unused_result__
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define to `int' if <sys/types.h> does not define. */
#undef pid_t
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t
/* Define to empty if the keyword `volatile' does not work. Warning: valid
code using `volatile' can become incorrect without. Disable with care. */
#undef volatile

36
config.sub vendored
View file

@ -1,8 +1,8 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright 1992-2014 Free Software Foundation, Inc.
# Copyright 1992-2015 Free Software Foundation, Inc.
timestamp='2014-09-11'
timestamp='2015-08-20'
# 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
@ -25,7 +25,7 @@ timestamp='2014-09-11'
# of the GNU General Public License, version 3 ("GPLv3").
# Please send patches with a ChangeLog entry to config-patches@gnu.org.
# Please send patches to <config-patches@gnu.org>.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
@ -68,7 +68,7 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
Copyright 1992-2014 Free Software Foundation, Inc.
Copyright 1992-2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@ -117,7 +117,7 @@ maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
knetbsd*-gnu* | netbsd*-gnu* | \
knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
kopensolaris*-gnu* | \
storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
@ -255,12 +255,13 @@ case $basic_machine in
| arc | arceb \
| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
| avr | avr32 \
| ba \
| be32 | be64 \
| bfin \
| c4x | c8051 | clipper \
| d10v | d30v | dlx | dsp16xx \
| epiphany \
| fido | fr30 | frv \
| e2k | epiphany \
| fido | fr30 | frv | ft32 \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \
| i370 | i860 | i960 | ia64 \
@ -305,7 +306,7 @@ case $basic_machine in
| riscv32 | riscv64 \
| rl78 | rx \
| score \
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
@ -313,6 +314,7 @@ case $basic_machine in
| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
| ubicom32 \
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
| visium \
| we32k \
| x86 | xc16x | xstormy16 | xtensa \
| z8k | z80)
@ -327,6 +329,9 @@ case $basic_machine in
c6x)
basic_machine=tic6x-unknown
;;
leon|leon[3-9])
basic_machine=sparc-$basic_machine
;;
m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
basic_machine=$basic_machine-unknown
os=-none
@ -372,12 +377,13 @@ case $basic_machine in
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* | avr32-* \
| ba-* \
| be32-* | be64-* \
| bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* \
| c8051-* | clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| e2k-* | elxsi-* \
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
@ -424,12 +430,13 @@ case $basic_machine in
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
| pyramid-* \
| riscv32-* | riscv64-* \
| rl78-* | romp-* | rs6000-* | rx-* \
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
| sparclite-* \
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
| tahoe-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
| tile*-* \
@ -437,6 +444,7 @@ case $basic_machine in
| ubicom32-* \
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
| vax-* \
| visium-* \
| we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* \
| xstormy16-* | xtensa*-* \
@ -513,6 +521,9 @@ case $basic_machine in
basic_machine=i386-pc
os=-aros
;;
asmjs)
basic_machine=asmjs-unknown
;;
aux)
basic_machine=m68k-apple
os=-aux
@ -774,6 +785,9 @@ case $basic_machine in
basic_machine=m68k-isi
os=-sysv
;;
leon-*|leon[3-9]-*)
basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
;;
m68knommu)
basic_machine=m68k-unknown
os=-linux
@ -1365,7 +1379,7 @@ case $os in
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
| -sym* | -kopensolaris* | -plan9* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
| -aos* | -aros* \
| -aos* | -aros* | -cloudabi* | -sortix* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \

1043
configure vendored

File diff suppressed because it is too large Load diff

View file

@ -1,11 +1,13 @@
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.61)
AC_INIT([tinc], [1.1pre11])
AC_INIT([tinc], m4_esyscmd_s((git describe || echo UNKNOWN) | sed 's/release-//'))
AC_CONFIG_SRCDIR([src/tincd.c])
AC_GNU_SOURCE
AM_INIT_AUTOMAKE([check-news std-options subdir-objects -Wall])
AM_INIT_AUTOMAKE([std-options subdir-objects nostdinc silent-rules -Wall])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
AM_SILENT_RULES([yes])
# Enable GNU extensions.
# Define this here, not in acconfig's @TOP@ section, since definitions
@ -66,7 +68,9 @@ case $host_os in
*mingw*)
mingw=true
AC_DEFINE(HAVE_MINGW, 1, [MinGW])
LIBS="$LIBS -lws2_32 -lgdi32 -lcrypt32"
LIBS="$LIBS -lws2_32 -lgdi32 -lcrypt32 -liphlpapi"
LDFLAGS="$LDFLAGS -static"
CPPFLAGS="$CPPFLAGS -DMINIUPNP_STATICLIB"
;;
*)
AC_MSG_ERROR("Unknown operating system.")
@ -107,13 +111,17 @@ AC_ARG_ENABLE(tunemu,
[tunemu=false]
)
AC_ARG_WITH(windows2000,
AS_HELP_STRING([--with-windows2000], [compile with support for Windows 2000. This disables support for tunneling over existing IPv6 networks.]),
[ AS_IF([test "x$with_windows2000" = "xyes"],
[AC_DEFINE(WITH_WINDOWS2000, 1, [Compile with support for Windows 2000])])
]
AC_ARG_WITH(systemd,
AS_HELP_STRING([--with-systemd@<:@=DIR@:>@], [install systemd service files @<:@to DIR if specified@:>@]),
[ systemd=true; systemd_path="$with_systemd" ],
[ systemd=false ]
)
AS_IF([test "x$with_systemd" = "xyes"], [systemd_path="/lib/systemd/system"],
[AS_IF([test "x$with_systemd" = "xno"], [systemd=false])])
AC_SUBST(systemd_path, $systemd_path)
AM_CONDITIONAL(LINUX, test "$linux" = true)
AM_CONDITIONAL(BSD, test "$bsd" = true)
AM_CONDITIONAL(SOLARIS, test "$solaris" = true)
@ -122,15 +130,12 @@ AM_CONDITIONAL(CYGWIN, test "$cygwin" = true)
AM_CONDITIONAL(UML, test "$uml" = true)
AM_CONDITIONAL(VDE, test "$vde" = true)
AM_CONDITIONAL(TUNEMU, test "$tunemu" = true)
AM_CONDITIONAL(WITH_SYSTEMD, test "$systemd" = true)
AC_CACHE_SAVE
if test -d /sw/include ; then
CPPFLAGS="$CPPFLAGS -I/sw/include"
fi
if test -d /sw/lib ; then
LIBS="$LIBS -L/sw/lib"
fi
AS_IF([test -d /sw/include], [CPPFLAGS="$CPPFLAGS -I/sw/include"])
AS_IF([test -d /sw/lib], [LIBS="$LIBS -L/sw/lib"])
dnl Compiler hardening flags
dnl No -fstack-protector-all because it doesn't work on all platforms or architectures.
@ -138,8 +143,8 @@ dnl No -fstack-protector-all because it doesn't work on all platforms or archite
AC_ARG_ENABLE([hardening], AS_HELP_STRING([--disable-hardening], [disable compiler and linker hardening flags]))
AS_IF([test "x$enable_hardening" != "xno"],
[AX_CHECK_COMPILE_FLAG([-DFORTIFY_SOURCE=2], [CPPFLAGS="$CPPFLAGS -DFORTIFY_SOURCE=2"])
AX_CHECK_COMPILE_FLAG([-fno-strict-overflow], [CPPFLAGS="$CPPFLAGS -fno-strict-overflow"])
AX_CHECK_COMPILE_FLAG([-fwrapv], [CPPFLAGS="$CPPFLAGS -fwrapv"])
AX_CHECK_COMPILE_FLAG([-fwrapv], [CPPFLAGS="$CPPFLAGS -fwrapv"],
AX_CHECK_COMPILE_FLAG([-fno-strict-overflow], [CPPFLAGS="$CPPFLAGS -fno-strict-overflow"]))
case $host_os in
*mingw*)
AX_CHECK_LINK_FLAG([-Wl,--dynamicbase], [LDFLAGS="$LDFLAGS -Wl,--dynamicbase"])
@ -158,79 +163,90 @@ AS_IF([test "x$enable_hardening" != "xno"],
dnl Checks for header files.
dnl We do this in multiple stages, because unlike Linux all the other operating systems really suck and don't include their own dependencies.
AC_HEADER_STDC
AC_CHECK_HEADERS([stdbool.h syslog.h sys/file.h sys/ioctl.h sys/mman.h sys/param.h sys/resource.h sys/socket.h sys/time.h sys/uio.h sys/un.h sys/wait.h netdb.h arpa/inet.h dirent.h])
AC_CHECK_HEADERS([net/if.h net/if_types.h linux/if_tun.h net/if_tun.h net/tun/if_tun.h net/if_tap.h net/tap/if_tap.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h time.h netpacket/packet.h],
[], [], [#include "src/have.h"]
AC_CHECK_HEADERS([syslog.h sys/file.h sys/ioctl.h sys/mman.h sys/param.h sys/resource.h sys/socket.h sys/time.h sys/un.h sys/wait.h netdb.h arpa/inet.h dirent.h getopt.h])
AC_CHECK_HEADERS([net/if.h net/if_types.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h netpacket/packet.h],
[], [], [#include "$srcdir/src/have.h"]
)
AC_CHECK_HEADERS([netinet/if_ether.h netinet/ip.h netinet/ip6.h resolv.h],
[], [], [#include "src/have.h"]
[], [], [#include "$srcdir/src/have.h"]
)
AC_CHECK_HEADERS([netinet/tcp.h netinet/ip_icmp.h netinet/icmp6.h],
[], [], [#include "src/have.h"]
[], [], [#include "$srcdir/src/have.h"]
)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_C_VOLATILE
AC_TYPE_PID_T
AC_TYPE_SIZE_T
AC_HEADER_TIME
AC_STRUCT_TM
tinc_ATTRIBUTE(__malloc__)
tinc_ATTRIBUTE(__warn_unused_result__)
AC_CHECK_TYPES([socklen_t, struct ether_header, struct arphdr, struct ether_arp, struct in_addr, struct addrinfo, struct ip, struct icmp, struct in6_addr, struct sockaddr_in6, struct ip6_hdr, struct icmp6_hdr, struct nd_neighbor_solicit, struct nd_opt_hdr], , ,
[#include "src/have.h"]
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], , ,
[#include "$srcdir/src/have.h"]
)
dnl Checks for library functions.
AC_TYPE_SIGNAL
AC_CHECK_FUNCS([asprintf daemon fchmod flock ftime fork get_current_dir_name gettimeofday mlockall putenv random select strdup strerror strsignal strtol system time usleep unsetenv vsyslog writev],
[], [], [#include "src/have.h"]
AC_CHECK_FUNCS([asprintf daemon fchmod flock ftime fork gettimeofday mlockall putenv recvmmsg strsignal nanosleep unsetenv vsyslog devname fdevname],
[], [], [#include "$srcdir/src/have.h"]
)
dnl Support for SunOS
AC_CHECK_FUNC(socket, [], [
AC_CHECK_LIB(socket, connect)
])
AC_CHECK_FUNC(gethostbyname, [], [
AC_CHECK_LIB(nsl, gethostbyname)
])
AC_CHECK_DECLS([freeaddrinfo, gai_strerror, getaddrinfo, getnameinfo],
[], [], [#include "src/have.h"]
)
AC_CHECK_FUNC(getopt_long, [getopt=true; AC_DEFINE(HAVE_GETOPT_LONG, 1, [getopt_long()])], [getopt=false])
AM_CONDITIONAL(GETOPT, test "$getopt" = true)
AC_CHECK_DECLS([res_init], [AC_CHECK_LIB(resolv, res_init)], [], [
#include <netinet/in.h>
#include <resolv.h>
])
dnl Operating system specific checks
case $host_os in
*linux*)
AC_CHECK_HEADERS([linux/if_tun.h],
[], [AC_MSG_ERROR([Required header file missng])], [#include "$srcdir/src/have.h"]
)
;;
*bsd*|*dragonfly*|*darwin*)
AC_CHECK_HEADERS([net/if_tun.h net/if_utun.h net/tun/if_tun.h net/if_tap.h net/tap/if_tap.h],
[], [], [#include "$srcdir/src/have.h"]
)
;;
*solaris*)
AC_CHECK_FUNC(socket, [], [AC_CHECK_LIB(socket, connect)])
;;
*)
;;
esac
AC_CACHE_SAVE
AC_ARG_ENABLE(legacy-protocol,
AS_HELP_STRING([--disable-legacy-protocol], [disable support for the legacy (tinc 1.0) protocol]),
[ AS_IF([test "x$enable_legacy_protocol" = "xno"],
[ AC_DEFINE(DISABLE_LEGACY, 1, [Disable support for the legacy (tinc 1.0) protocol]) ])
]
)
dnl These are defined in files in m4/
dnl AC_ARG_WITH(libgcrypt, AC_HELP_STRING([--with-libgcrypt], [enable use of libgcrypt instead of OpenSSL])], [])
dnl AC_ARG_WITH(openssl, AC_HELP_STRING([--without-openssl], [disable support for OpenSSL])], [])
tinc_CURSES
tinc_READLINE
tinc_ZLIB
tinc_LZO
if test -n "$with_libgcrypt"; then
gcrypt=true
tinc_LIBGCRYPT
else
openssl=true
tinc_OPENSSL
fi
AS_IF([test "x$enable_legacy_protocol" != "xno"],
[AS_IF([test -n "$with_libgcrypt"],
[gcrypt=true; tinc_LIBGCRYPT],
[openssl=true; tinc_OPENSSL])
]
)
AM_CONDITIONAL(OPENSSL, test -n "$openssl")
AM_CONDITIONAL(GCRYPT, test -n "$gcrypt")
tinc_MINIUPNPC
AM_CONDITIONAL(MINIUPNPC, test "x$enable_miniupnpc" = "xyes")
dnl Check if support for jumbograms is requested
AC_ARG_ENABLE(jumbograms,
AS_HELP_STRING([--enable-jumbograms], [enable support for jumbograms (packets up to 9000 bytes)]),
@ -239,6 +255,6 @@ AC_ARG_ENABLE(jumbograms,
]
)
AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile m4/Makefile gui/Makefile test/Makefile])
AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile gui/Makefile test/Makefile systemd/Makefile])
AC_OUTPUT

View file

@ -3,7 +3,7 @@
scriptversion=2013-05-30.07; # UTC
# Copyright (C) 1999-2013 Free Software Foundation, Inc.
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View file

@ -6,7 +6,7 @@ man_MANS = tincd.8 tinc.8 tinc.conf.5 tinc-gui.8
EXTRA_DIST = tincinclude.texi.in tincd.8.in tinc.8.in tinc.conf.5.in tinc-gui.8.in sample-config.tar.gz
CLEANFILES = *.html tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi
CLEANFILES = *.html tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi sample-config.tar.gz
# Use `ginstall' in the definition of man_MANS to avoid
# confusion with the `install' target. The install rule transforms `ginstall'
@ -17,19 +17,19 @@ transform = s/ginstall/install/; @program_transform_name@
# see GNUmakefile and Makefile.maint.
sample-config.tar.gz: sample-config
GZIP=$(GZIP_ENV) $(AMTAR) chozf sample-config.tar.gz --exclude .svn sample-config
$(AM_V_GEN)GZIP=$(GZIP_ENV) $(AMTAR) chozf $@ --exclude .svn $<
tincd.8.html: tincd.8
w3mman2html $? > $@
$(AM_V_GEN)w3mman2html $? > $@
tinc.8.html: tinc.8
w3mman2html $? > $@
$(AM_V_GEN)w3mman2html $? > $@
tinc-gui.8.html: tinc-gui.8
w3mman2html $? > $@
$(AM_V_GEN)w3mman2html $? > $@
tinc.conf.5.html: tinc.conf.5
w3mman2html $? > $@
$(AM_V_GEN)w3mman2html $? > $@
substitute = sed \
-e s,'@PACKAGE\@',"$(PACKAGE)",g \
@ -38,18 +38,18 @@ substitute = sed \
-e s,'@localstatedir\@',"$(localstatedir)",g
tincd.8: tincd.8.in
$(substitute) $? > $@
$(AM_V_GEN)$(substitute) $? > $@
tinc.8: tinc.8.in
$(substitute) $? > $@
$(AM_V_GEN)$(substitute) $? > $@
tinc-gui.8: tinc-gui.8.in
$(substitute) $? > $@
$(AM_V_GEN)$(substitute) $? > $@
tinc.conf.5: tinc.conf.5.in
$(substitute) $? > $@
$(AM_V_GEN)$(substitute) $? > $@
tincinclude.texi: tincinclude.texi.in
$(substitute) $? > $@
$(AM_V_GEN)$(substitute) $? > $@
tinc.texi: tincinclude.texi

View file

@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.14.1 from Makefile.am.
# Makefile.in generated by automake 1.15 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# Copyright (C) 1994-2014 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -14,7 +14,17 @@
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
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 \
?) ;; \
@ -77,17 +87,17 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = doc
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am texinfo.tex
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
$(top_srcdir)/m4/ax_check_link_flag.m4 \
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \
$(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \
$(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \
$(top_srcdir)/configure.ac
$(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 $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
@ -185,6 +195,7 @@ man8dir = $(mandir)/man8
NROFF = nroff
MANS = $(man_MANS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
am__DIST_COMMON = $(srcdir)/Makefile.in texinfo.tex
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
# Use `ginstall' in the definition of man_MANS to avoid
@ -224,6 +235,7 @@ LIBS = @LIBS@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MINIUPNPC_LIBS = @MINIUPNPC_LIBS@
MKDIR_P = @MKDIR_P@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
@ -281,10 +293,12 @@ 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@
@ -292,7 +306,7 @@ top_srcdir = @top_srcdir@
info_TEXINFOS = tinc.texi
man_MANS = tincd.8 tinc.8 tinc.conf.5 tinc-gui.8
EXTRA_DIST = tincinclude.texi.in tincd.8.in tinc.8.in tinc.conf.5.in tinc-gui.8.in sample-config.tar.gz
CLEANFILES = *.html tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi
CLEANFILES = *.html tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi sample-config.tar.gz
substitute = sed \
-e s,'@PACKAGE\@',"$(PACKAGE)",g \
-e s,'@VERSION\@',"$(VERSION)",g \
@ -315,7 +329,6 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu doc/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@ -816,39 +829,41 @@ uninstall-man: uninstall-man5 uninstall-man8
uninstall-html-am uninstall-info-am uninstall-man \
uninstall-man5 uninstall-man8 uninstall-pdf-am uninstall-ps-am
.PRECIOUS: Makefile
# For additional rules usually of interest only to the maintainer,
# see GNUmakefile and Makefile.maint.
sample-config.tar.gz: sample-config
GZIP=$(GZIP_ENV) $(AMTAR) chozf sample-config.tar.gz --exclude .svn sample-config
$(AM_V_GEN)GZIP=$(GZIP_ENV) $(AMTAR) chozf $@ --exclude .svn $<
tincd.8.html: tincd.8
w3mman2html $? > $@
$(AM_V_GEN)w3mman2html $? > $@
tinc.8.html: tinc.8
w3mman2html $? > $@
$(AM_V_GEN)w3mman2html $? > $@
tinc-gui.8.html: tinc-gui.8
w3mman2html $? > $@
$(AM_V_GEN)w3mman2html $? > $@
tinc.conf.5.html: tinc.conf.5
w3mman2html $? > $@
$(AM_V_GEN)w3mman2html $? > $@
tincd.8: tincd.8.in
$(substitute) $? > $@
$(AM_V_GEN)$(substitute) $? > $@
tinc.8: tinc.8.in
$(substitute) $? > $@
$(AM_V_GEN)$(substitute) $? > $@
tinc-gui.8: tinc-gui.8.in
$(substitute) $? > $@
$(AM_V_GEN)$(substitute) $? > $@
tinc.conf.5: tinc.conf.5.in
$(substitute) $? > $@
$(AM_V_GEN)$(substitute) $? > $@
tincinclude.texi: tincinclude.texi.in
$(substitute) $? > $@
$(AM_V_GEN)$(substitute) $? > $@
tinc.texi: tincinclude.texi

Binary file not shown.

View file

@ -11,6 +11,7 @@
.Op Fl -config Ns = Ns Ar DIR
.Op Fl -net Ns = Ns Ar NETNAME
.Op Fl -pidfile Ns = Ns Ar FILENAME
.Op Fl -force
.Op Fl -help
.Op Fl -version
.Op Ar COMMAND
@ -54,6 +55,8 @@ Use the cookie from
to authenticate with a running tinc daemon.
If unspecified, the default is
.Pa @localstatedir@/run/tinc. Ns Ar NETNAME Ns Pa .pid.
.It Fl -force
Force some commands to work despite warnings.
.It Fl -help
Display short list of options.
.It Fl -version
@ -88,6 +91,7 @@ To set a variable for a specific host, use the notation
.Ar host Ns Li . Ns Ar variable .
.It add Ar variable Ar value
As above, but without removing any previously existing configuration variables.
If the variable already exists with the given value, nothing happens.
.It del Ar variable Op Ar value
Remove configuration variables with the same name and
.Ar value .
@ -101,16 +105,16 @@ You do not need to specify the full path to the file.
Export the host configuration file of the local node to standard output.
.It export-all
Export all host configuration files to standard output.
.It import Op Fl -force
.It import
Import host configuration data generated by the
.Nm
export command from standard input.
Already existing host configuration files are not overwritten unless the option
.Fl -force
is used.
.It exchange Op Fl -force
.It exchange
The same as export followed by import.
.It exchange-all Op Fl -force
.It exchange-all
The same as export-all followed by import.
.It invite Ar name
Prepares an invitation for a new node with the given
@ -168,6 +172,9 @@ format.
Nodes are colored according to their reachability:
red nodes are unreachable, orange nodes are indirectly reachable, green nodes are directly reachable.
Black nodes are either directly or indirectly reachable, but direct reachability has not been tried yet.
.It dump invitations
Dump a list of outstanding invitations.
The filename of the invitation, as well as the name of the node that is being invited is shown for each invitation.
.It info Ar node | subnet | address
Show information about a particular node, subnet or address.
If an address is given, any matching subnet will be shown.
@ -215,6 +222,38 @@ If
.Ar netname
is given, switch to that network.
Otherwise, display a list of all networks for which configuration files exist.
.It fsck
This will check the configuration files for possible problems,
such as unsafe file permissions, missing executable bit on script,
unknown and obsolete configuration variables, wrong public and/or private keys, and so on.
.Pp
When problems are found, this will be printed on a line with WARNING or ERROR in front of it.
Most problems must be corrected by the user itself, however in some cases (like file permissions and missing public keys),
tinc will ask if it should fix the problem.
.It sign Op Ar filename
Sign a file with the local node's private key.
If no
.Ar filename
is given, the file is read from standard input.
The signed file is written to standard output.
.It verify Ar name Op Ar filename
Check the signature of a file against a node's public key.
The
.Ar name
of the node must be given,
or can be
.Li .
to check against the local node's public key, or
.Li *
to allow a signature from any node whose public key is known.
If no
.Ar filename
is given, the file is read from standard input.
If the verification is succesful,
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.
.El
.Sh EXAMPLES
Examples of some commands:

View file

@ -1,4 +1,4 @@
.Dd 2014-01-29
.Dd 2016-04-11
.Dt TINC.CONF 5
.\" Manual page created by:
.\" Ivo Timmermans
@ -42,7 +42,7 @@ the configuration file should be
and the host configuration files are now expected to be in
.Pa @sysconfdir@/tinc/hosts/ .
.Sh NAMES
Each tinc daemon should have a name that is unique in the network which it will be part of.
Each tinc daemon must have a name that is unique in the network which it will be part of.
The name will be used by other tinc daemons for identification.
The name has to be declared in the
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf
@ -266,6 +266,10 @@ Tinc will expect packets read from the virtual network device
to start with a four byte header containing the address family,
followed by an IP header.
This mode should support both IPv4 and IPv6 packets.
.It utun Pq OS X
Set type to utun.
This is only supported on OS X version 10.6.8 and higher, but doesn't require the tuntaposx module.
This mode should support both IPv4 and IPv6 packets.
.It tap Pq BSD and Linux
Set type to tap.
Tinc will expect packets read from the virtual network device
@ -358,7 +362,7 @@ This will allow direct communication using LAN addresses, even if both peers are
and they only ConnectTo a third node outside the NAT,
which normally would prevent the peers from learning each other's LAN address.
.Pp
Currently, local discovery is implemented by sending some packets to the local address of the node during path MTU discovery. This will not work with old nodes that don't transmit their local address.
Currently, local discovery is implemented by sending some packets to the local address of the node during UDP discovery. This will not work with old nodes that don't transmit their local address.
.It Va MACExpire Li = Ar seconds Pq 600
This option controls the amount of time MAC addresses are kept before they are removed.
This only has effect when
@ -464,10 +468,10 @@ and
.Ev REMOTEPORT
are available.
.El
.It Va ReplayWindow Li = Ar bytes Pq 16
.It Va ReplayWindow Li = Ar bytes Pq 32
This is the size of the replay tracking window for each remote node, in bytes.
The window is a bitfield which tracks 1 packet per bit, so for example
the default setting of 16 will track up to 128 packets in the window. In high
the default setting of 32 will track up to 256 packets in the window. In high
bandwidth scenarios, setting this to a higher value can reduce packet loss from
the interaction of replay tracking with underlying real packet loss and/or
reordering. Setting this to zero will disable replay tracking completely and
@ -485,12 +489,42 @@ and will only allow connections with nodes for which host config files are prese
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/
directory.
Setting this options also implicitly sets StrictSubnets.
.It Va UDPRcvBuf Li = Ar bytes Pq OS default
.It Va UDPDiscovery Li = yes | no Po yes Pc
When this option is enabled tinc will try to establish UDP connectivity to nodes,
using TCP while it determines if a node is reachable over UDP. If it is disabled,
tinc always assumes a node is reachable over UDP.
Note that tinc will never use UDP with nodes that have
.Va TCPOnly
enabled.
.It Va UDPDiscoveryKeepaliveInterval Li = Ar seconds Pq 9
The minimum amount of time between sending UDP ping datagrams to check UDP connectivity once it has been established.
Note that these pings are large, since they are used to verify link MTU as well.
.It Va UDPDiscoveryInterval Li = Ar seconds Pq 2
The minimum amount of time between sending UDP ping datagrams to try to establish UDP connectivity.
.It Va UDPDiscoveryTimeout Li = Ar seconds Pq 30
If tinc doesn't receive any UDP ping replies over the specified interval,
it will assume UDP communication is broken and will fall back to TCP.
.It Va UDPInfoInterval Li = Ar seconds Pq 5
The minimum amount of time between sending periodic updates about UDP addresses, which are mostly useful for UDP hole punching.
.It Va UDPRcvBuf Li = Ar bytes Pq 1048576
Sets the socket receive buffer size for the UDP socket, in bytes.
If unset, the default buffer size will be used by the operating system.
.It Va UDPSndBuf Li = Ar bytes Pq OS default
If set to zero, the default buffer size will be used by the operating system.
Note: this setting can have a significant impact on performance, especially raw throughput.
.It Va UDPSndBuf Li = Ar bytes Pq 1048576
Sets the socket send buffer size for the UDP socket, in bytes.
If unset, the default buffer size will be used by the operating system.
If set to zero, the default buffer size will be used by the operating system.
Note: this setting can have a significant impact on performance, especially raw throughput.
.It Va UPnP Li = yes | udponly | no Po no Pc
If this option is enabled then tinc will search for UPnP-IGD devices on the local network.
It will then create and maintain port mappings for tinc's listening TCP and UDP ports.
If set to "udponly", tinc will only create a mapping for its UDP (data) port, not for its TCP (metaconnection) port.
Note that tinc must have been built with miniupnpc support for this feature to be available.
Furthermore, be advised that enabling this can have security implications, because the miniupnpc library that
tinc uses might not be well-hardened with regard to malicious UPnP replies.
.It Va UPnPDiscoverWait Li = Ar seconds Pq 5
The amount of time to wait for replies when probing the local network for UPnP devices.
.It Va UPnPRefreshPeriod Li = Ar seconds Pq 60
How often tinc will re-add the port mapping, in case it gets reset on the UPnP device. This also controls the duration of the port mapping itself, which will be set to twice that duration.
.El
.Sh HOST CONFIGURATION FILES
The host configuration files contain all information needed
@ -515,7 +549,7 @@ variables can be specified, in which case each address will be tried until a wor
connection has been established.
.It Va Cipher Li = Ar cipher Pq blowfish
The symmetric cipher algorithm used to encrypt UDP packets.
Any cipher supported by OpenSSL is recognised.
Any cipher supported by LibreSSL or OpenSSL is recognised.
Furthermore, specifying
.Qq none
will turn off packet encryption.
@ -532,7 +566,7 @@ Possible values are 0 (off), 1 (fast zlib) and any integer up to 9 (best zlib),
10 (fast lzo) and 11 (best lzo).
.It Va Digest Li = Ar digest Pq sha1
The digest algorithm used to authenticate UDP packets.
Any digest supported by OpenSSL is recognised.
Any digest supported by LibreSSL or OpenSSL is recognised.
Furthermore, specifying
.Qq none
will turn off packet authentication.
@ -554,6 +588,8 @@ This option controls the initial path MTU to this node.
.It Va PMTUDiscovery Li = yes | no Po yes Pc
When this option is enabled, tinc will try to discover the path MTU to this node.
After the path MTU has been discovered, it will be enforced on the VPN.
.It Va MTUInfoInterval Li = Ar seconds Pq 5
The minimum amount of time between sending periodic updates about relay path MTU. Useful for quickly determining MTU to indirect nodes.
.It Va Port Li = Ar port Pq 655
The port number on which this tinc daemon is listening for incoming connections,
which is used if no port number is specified in an
@ -625,10 +661,18 @@ forwarding packets.
.Sh SCRIPTS
Apart from reading the server and host configuration files,
tinc can also run scripts at certain moments.
Under Windows (not Cygwin), the scripts should have the extension
Below is a list of filenames of scripts and a description of when they are run.
A script is only run if it exists and if it is executable.
.Pp
Scripts are run synchronously;
this means that tinc will temporarily stop processing packets until the called script finishes executing.
This guarantees that scripts will execute in the exact same order as the events that trigger them.
If you need to run commands asynchronously, you have to ensure yourself that they are being run in the background.
.Pp
Under Windows (not Cygwin), the scripts must have the extension
.Pa .bat
or
.Pa cmd .
.Pa .cmd .
.Bl -tag -width indent
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-up
This is the most important script.
@ -637,6 +681,7 @@ If it is present it will be executed right after the tinc daemon has been starte
is used).
It should be used to set up the corresponding network interface,
but can also be used to start other things.
.Pp
Under Windows you can use the Network Connections control panel instead of creating this script.
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-down
This script is started right before the tinc daemon quits (or when the last node becomes unreachable if
@ -734,7 +779,7 @@ its connection to the virtual network device.
.Sh SEE ALSO
.Xr tincd 8 ,
.Xr tinc 8 ,
.Pa http://www.tinc-vpn.org/ ,
.Pa https://www.tinc-vpn.org/ ,
.Pa http://www.tldp.org/LDP/nag2/ .
.Pp
The full documentation for

File diff suppressed because it is too large Load diff

View file

@ -15,7 +15,7 @@
This is the info manual for @value{PACKAGE} version @value{VERSION}, a Virtual Private Network daemon.
Copyright @copyright{} 1998-2014 Ivo Timmermans,
Copyright @copyright{} 1998-2016 Ivo Timmermans,
Guus Sliepen <guus@@tinc-vpn.org> and
Wessel Dankers <wsl@@tinc-vpn.org>.
@ -43,7 +43,7 @@ permission notice identical to this one.
@vskip 0pt plus 1filll
This is the info manual for @value{PACKAGE} version @value{VERSION}, a Virtual Private Network daemon.
Copyright @copyright{} 1998-2014 Ivo Timmermans,
Copyright @copyright{} 1998-2016 Ivo Timmermans,
Guus Sliepen <guus@@tinc-vpn.org> and
Wessel Dankers <wsl@@tinc-vpn.org>.
@ -70,6 +70,7 @@ permission notice identical to this one.
* Configuration::
* Running tinc::
* Controlling tinc::
* Invitations::
* Technical information::
* Platform specific information::
* About us::
@ -191,7 +192,7 @@ packets.
@cindex release
For an up to date list of supported platforms, please check the list on
our website:
@uref{http://www.tinc-vpn.org/platforms/}.
@uref{https://www.tinc-vpn.org/platforms/}.
@c
@c
@ -273,12 +274,7 @@ The tap driver can be loaded with @code{kldload if_tap}, or by adding @code{if_t
@node Configuration of OpenBSD kernels
@subsection Configuration of OpenBSD kernels
For OpenBSD version 2.9 and higher,
the tun driver is included in the default kernel configuration.
There is also a kernel patch from @uref{http://diehard.n-r-g.com/stuff/openbsd/}
which adds a tap device to OpenBSD which should work with tinc,
but with recent versions of OpenBSD,
a tun device can act as a tap device by setting the link0 option with ifconfig.
Recent versions of OpenBSD come with both tun and tap devices enabled in the default kernel configuration.
@c ==================================================================
@ -298,7 +294,7 @@ Tunneling IPv6 may not work on NetBSD's tun device.
For Solaris 8 (SunOS 5.8) and higher,
the tun driver may or may not be included in the default kernel configuration.
If it isn't, the source can be downloaded from @uref{http://vtun.sourceforge.net/tun/}.
For x86 and sparc64 architectures, precompiled versions can be found at @uref{http://www.monkey.org/~dugsong/fragroute/}.
For x86 and sparc64 architectures, precompiled versions can be found at @uref{https://www.monkey.org/~dugsong/fragroute/}.
If the @file{net/if_tun.h} header file is missing, install it from the source package.
@ -307,15 +303,14 @@ If the @file{net/if_tun.h} header file is missing, install it from the source pa
@subsection Configuration of Darwin (MacOS/X) kernels
Tinc on Darwin relies on a tunnel driver for its data acquisition from the kernel.
Tinc supports either the driver from @uref{http://tuntaposx.sourceforge.net/},
OS X version 10.6.8 and later have a built-in tun driver called "utun".
Tinc also supports the driver from @uref{http://tuntaposx.sourceforge.net/},
which supports both tun and tap style devices,
and also the driver from from @uref{http://chrisp.de/en/projects/tunnel.html}.
The former driver is recommended.
The tunnel driver must be loaded before starting tinc with the following command:
@example
kmodload tunnel
@end example
By default, tinc expects the tuntaposx driver to be installed.
To use the utun driver, set add @code{Device = utunX} to @file{tinc.conf},
where X is the desired number for the utun interface.
You can also omit the number, in which case the first free number will be chosen.
@c ==================================================================
@ -323,7 +318,7 @@ kmodload tunnel
@subsection Configuration of Windows
You will need to install the latest TAP-Win32 driver from OpenVPN.
You can download it from @uref{http://openvpn.sourceforge.net}.
You can download it from @uref{https://openvpn.net/index.php/open-source/downloads.html}.
Using the Network Connections control panel,
configure the TAP-Win32 network interface in the same way as you would do from the tinc-up script,
as explained in the rest of the documentation.
@ -335,13 +330,13 @@ as explained in the rest of the documentation.
@cindex requirements
@cindex libraries
Before you can configure or build tinc, you need to have the 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
configure tinc without having them installed, configure will give you an error
message, and stop.
@menu
* OpenSSL::
* LibreSSL/OpenSSL::
* zlib::
* lzo::
* libcurses::
@ -350,12 +345,13 @@ message, and stop.
@c ==================================================================
@node OpenSSL
@subsection OpenSSL
@node LibreSSL/OpenSSL
@subsection LibreSSL/OpenSSL
@cindex LibreSSL
@cindex OpenSSL
For all cryptography-related functions, tinc uses the functions provided
by the OpenSSL library.
by the LibreSSL or the OpenSSL library.
If this library is not installed, you wil get an error when configuring
tinc for build. Support for running tinc with other cryptographic libraries
@ -365,21 +361,23 @@ You can use your operating system's package manager to install this if
available. Make sure you install the development AND runtime versions
of this package.
If you have to install OpenSSL manually, you can get the source code
from @url{http://www.openssl.org/}. Instructions on how to configure,
build and install this package are included within the package. Please
make sure you build development and runtime libraries (which is the
If your operating system comes neither with LibreSSL or OpenSSL, you have to
install one manually. It is recommended that you get the latest version of
LibreSSL from @url{http://www.libressl.org/}. Instructions on how to
configure, build and install this package are included within the package.
Please make sure you build development and runtime libraries (which is the
default).
If you installed the OpenSSL libraries from source, it may be necessary
If you installed the LibreSSL or OpenSSL libraries from source, it may be necessary
to let configure know where they are, by passing configure one of the
--with-openssl-* parameters.
--with-openssl-* parameters. Note that you even have to use --with-openssl-* if you
are using LibreSSL.
@example
--with-openssl=DIR OpenSSL library and headers prefix
--with-openssl-include=DIR OpenSSL headers directory
--with-openssl=DIR LibreSSL/OpenSSL library and headers prefix
--with-openssl-include=DIR LibreSSL/OpenSSL headers directory
(Default is OPENSSL_DIR/include)
--with-openssl-lib=DIR OpenSSL library directory
--with-openssl-lib=DIR LibreSSL/OpenSSL library directory
(Default is OPENSSL_DIR/lib)
@end example
@ -390,7 +388,7 @@ to let configure know where they are, by passing configure one of the
The complete source code of tinc is covered by the GNU GPL version 2.
Since the license under which OpenSSL is distributed is not directly
compatible with the terms of the GNU GPL
@uref{http://www.openssl.org/support/faq.html#LEGAL2}, we
@uref{https://www.openssl.org/support/faq.html#LEGAL2}, we
include an exemption to the GPL (see also the file COPYING.README) to allow
everyone to create a statically or dynamically linked executable:
@ -406,8 +404,8 @@ we also present the following exemption:
@quotation
Hereby I grant a special exception to the tinc VPN project
(http://www.tinc-vpn.org/) to link the LZO library with the OpenSSL library
(http://www.openssl.org).
(https://www.tinc-vpn.org/) to link the LZO library with the OpenSSL library
(https://www.openssl.org).
Markus F.X.J. Oberhumer
@end quotation
@ -432,7 +430,7 @@ available. Make sure you install the development AND runtime versions
of this package.
If you have to install zlib manually, you can get the source code
from @url{http://www.gzip.org/zlib/}. Instructions on how to configure,
from @url{http://www.zlib.net/}. Instructions on how to configure,
build and install this package are included within the package. Please
make sure you build development and runtime libraries (which is the
default).
@ -456,7 +454,7 @@ available. Make sure you install the development AND runtime versions
of this package.
If you have to install lzo manually, you can get the source code
from @url{http://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
make sure you build development and runtime libraries (which is the
default).
@ -527,9 +525,7 @@ system startup scripts and sample configurations.
If you cannot use one of the precompiled packages, or you want to compile tinc
for yourself, you can use the source. The source is distributed under
the GNU General Public License (GPL). Download the source from the
@uref{http://www.tinc-vpn.org/download/, download page}, which has
the checksums of these files listed; you may wish to check these with
md5sum before continuing.
@uref{https://www.tinc-vpn.org/download/, download page}.
Tinc comes in a convenient autoconf/automake package, which you can just
treat the same as any other package. Which is just untar it, type
@ -566,19 +562,18 @@ The documentation that comes along with your distribution will tell you how to d
@node Darwin (MacOS/X) build environment
@subsection Darwin (MacOS/X) build environment
In order to build tinc on Darwin, you need to install the MacOS/X Developer Tools
from @uref{http://developer.apple.com/tools/macosxtools.html} and
a recent version of Fink from @uref{http://www.finkproject.org/}.
In order to build tinc on Darwin, you need to install Xcode from @uref{https://developer.apple.com/xcode/}.
It might also help to install a recent version of Fink from @uref{http://www.finkproject.org/}.
After installation use fink to download and install the following packages:
autoconf25, automake, dlcompat, m4, openssl, zlib and lzo.
You need to download and install LibreSSL (or OpenSSL) and LZO,
either directly from their websites (see @ref{Libraries}) or using Fink.
@c ==================================================================
@node Cygwin (Windows) build environment
@subsection Cygwin (Windows) build environment
If Cygwin hasn't already been installed, install it directly from
@uref{http://www.cygwin.com/}.
@uref{https://www.cygwin.com/}.
When tinc is compiled in a Cygwin environment, it can only be run in this environment,
but all programs, including those started outside the Cygwin environment, will be able to use the VPN.
@ -589,6 +584,7 @@ It will also support all features.
@subsection MinGW (Windows) build environment
You will need to install the MinGW environment from @uref{http://www.mingw.org}.
You also need to download and install LibreSSL (or OpenSSL) and LZO.
When tinc is compiled using MinGW it runs natively under Windows,
it is not necessary to keep MinGW installed.
@ -735,7 +731,7 @@ You will also notice that log messages it appears in syslog as coming from @file
and on Linux, unless specified otherwise, the name of the virtual network interface will be the same as the network name.
However, it is not strictly necessary that you call tinc with the -n
option. If you don not use it, the network name will just be empty, and
option. If you do not use it, the network name will just be empty, and
tinc will look for files in @file{@value{sysconfdir}/tinc/} instead of
@file{@value{sysconfdir}/tinc/@var{netname}/};
the configuration file will then be @file{@value{sysconfdir}/tinc/tinc.conf},
@ -999,6 +995,12 @@ to start with a four byte header containing the address family,
followed by an IP header.
This mode should support both IPv4 and IPv6 packets.
@cindex utun
@item utun (OS X)
Set type to utun.
This is only supported on OS X version 10.6.8 and higher, but doesn't require the tuntaposx module.
This mode should support both IPv4 and IPv6 packets.
@item tap (BSD and Linux)
Set type to tap.
Tinc will expect packets read from the virtual network device
@ -1081,8 +1083,8 @@ This will allow direct communication using LAN addresses, even if both peers are
and they only ConnectTo a third node outside the NAT,
which normally would prevent the peers from learning each other's LAN address.
Currently, local discovery is implemented by sending broadcast packets to the LAN during path MTU discovery.
This feature may not work in all possible situations.
Currently, local discovery is implemented by sending some packets to the local address of the node during UDP discovery.
This will not work with old nodes that don't transmit their local address.
@cindex LocalDiscoveryAddress
@item LocalDiscoveryAddress <@var{address}>
@ -1139,7 +1141,7 @@ until the burst has passed.
@cindex Name
@item Name = <@var{name}> [required]
This is a symbolic name for this connection.
The name should consist only of alfanumeric and underscore characters (a-z, A-Z, 0-9 and _), and is case sensitive.
The name must consist only of alfanumeric and underscore characters (a-z, A-Z, 0-9 and _), and is case sensitive.
If Name starts with a $, then the contents of the environment variable that follows will be used.
In that case, invalid characters will be converted to underscores.
@ -1207,10 +1209,10 @@ The environment variables @env{NAME}, @env{NODE}, @env{REMOTEADDRES} and @env{RE
@end table
@cindex ReplayWindow
@item ReplayWindow = <bytes> (16)
@item ReplayWindow = <bytes> (32)
This is the size of the replay tracking window for each remote node, in bytes.
The window is a bitfield which tracks 1 packet per bit, so for example
the default setting of 16 will track up to 128 packets in the window. In high
the default setting of 32 will track up to 256 packets in the window. In high
bandwidth scenarios, setting this to a higher value can reduce packet loss from
the interaction of replay tracking with underlying real packet loss and/or
reordering. Setting this to zero will disable replay tracking completely and
@ -1232,15 +1234,60 @@ and will only allow connections with nodes for which host config files are prese
@file{@value{sysconfdir}/tinc/@var{netname}/hosts/} directory.
Setting this options also implicitly sets StrictSubnets.
@cindex UDPDiscovey
@item UDPDiscovery = <yes|no> (yes)
When this option is enabled tinc will try to establish UDP connectivity to nodes,
using TCP while it determines if a node is reachable over UDP. If it is disabled,
tinc always assumes a node is reachable over UDP.
Note that tinc will never use UDP with nodes that have TCPOnly enabled.
@cindex UDPDiscoveryKeepaliveInterval
@item UDPDiscoveryKeepaliveInterval = <seconds> (9)
The minimum amount of time between sending UDP ping datagrams to check UDP connectivity once it has been established.
Note that these pings are large, since they are used to verify link MTU as well.
@cindex UDPDiscoveryInterval
@item UDPDiscoveryInterval = <seconds> (2)
The minimum amount of time between sending UDP ping datagrams to try to establish UDP connectivity.
@cindex UDPDiscoveryTimeout
@item UDPDiscoveryTimeout = <seconds> (30)
If tinc doesn't receive any UDP ping replies over the specified interval,
it will assume UDP communication is broken and will fall back to TCP.
@cindex UDPInfoInterval
@item UDPInfoInterval = <seconds> (5)
The minimum amount of time between sending periodic updates about UDP addresses, which are mostly useful for UDP hole punching.
@cindex UDPRcvBuf
@item UDPRcvBuf = <bytes> (OS default)
@item UDPRcvBuf = <bytes> (1048576)
Sets the socket receive buffer size for the UDP socket, in bytes.
If unset, the default buffer size will be used by the operating system.
If set to zero, the default buffer size will be used by the operating system.
Note: this setting can have a significant impact on performance, especially raw throughput.
@cindex UDPSndBuf
@item UDPSndBuf = <bytes> Pq OS default
@item UDPSndBuf = <bytes> (1048576)
Sets the socket send buffer size for the UDP socket, in bytes.
If unset, the default buffer size will be used by the operating system.
If set to zero, the default buffer size will be used by the operating system.
Note: this setting can have a significant impact on performance, especially raw throughput.
@cindex UPnP
@item UPnP = <yes|udponly|no> (no)
If this option is enabled then tinc will search for UPnP-IGD devices on the local network.
It will then create and maintain port mappings for tinc's listening TCP and UDP ports.
If set to "udponly", tinc will only create a mapping for its UDP (data) port, not for its TCP (metaconnection) port.
Note that tinc must have been built with miniupnpc support for this feature to be available.
Furthermore, be advised that enabling this can have security implications, because the miniupnpc library that
tinc uses might not be well-hardened with regard to malicious UPnP replies.
@cindex UPnPDiscoverWait
@item UPnPDiscoverWait = <seconds> (5)
The amount of time to wait for replies when probing the local network for UPnP devices.
@cindex UPnPRefreshPeriod
@item UPnPRefreshPeriod = <seconds> (5)
How often tinc will re-add the port mapping, in case it gets reset on the UPnP device.
This also controls the duration of the port mapping itself, which will be set to twice that duration.
@end table
@ -1262,7 +1309,7 @@ tried until a working connection has been established.
@cindex Cipher
@item Cipher = <@var{cipher}> (blowfish)
The symmetric cipher algorithm used to encrypt UDP packets using the legacy protocol.
Any cipher supported by OpenSSL is recognized.
Any cipher supported by LibreSSL or OpenSSL is recognized.
Furthermore, specifying "none" will turn off packet encryption.
It is best to use only those ciphers which support CBC mode.
This option has no effect for connections using the SPTPS protocol, which always use AES-256-CTR.
@ -1282,7 +1329,7 @@ Possible values are 0 (off), 1 (fast zlib) and any integer up to 9 (best zlib),
@cindex Digest
@item Digest = <@var{digest}> (sha1)
The digest algorithm used to authenticate UDP packets using the legacy protocol.
Any digest supported by OpenSSL is recognized.
Any digest supported by LibreSSL or OpenSSL is recognized.
Furthermore, specifying "none" will turn off packet authentication.
This option has no effect for connections using the SPTPS protocol, which always use HMAC-SHA-256.
@ -1308,6 +1355,10 @@ This option controls the initial path MTU to this node.
When this option is enabled, tinc will try to discover the path MTU to this node.
After the path MTU has been discovered, it will be enforced on the VPN.
@cindex MTUInfoInterval
@item MTUInfoInterval = <seconds> (5)
The minimum amount of time between sending periodic updates about relay path MTU. Useful for quickly determining MTU to indirect nodes.
@cindex Port
@item Port = <@var{port}> (655)
This is the port this tinc daemon listens on.
@ -1353,7 +1404,7 @@ MAC addresses are notated like 0:1a:2b:3c:4d:5e.
Prefixlength is the number of bits set to 1 in the netmask part; for
example: netmask 255.255.255.0 would become /24, 255.255.252.0 becomes
/22. This conforms to standard CIDR notation as described in
@uref{http://www.ietf.org/rfc/rfc1519.txt, RFC1519}
@uref{https://www.ietf.org/rfc/rfc1519.txt, RFC1519}
A Subnet can be given a weight to indicate its priority over identical Subnets
owned by different nodes. The default weight is 10. Lower values indicate
@ -1384,6 +1435,14 @@ connection when broadcasting or forwarding packets.
@cindex scripts
Apart from reading the server and host configuration files,
tinc can also run scripts at certain moments.
Below is a list of filenames of scripts and a description of when they are run.
A script is only run if it exists and if it is executable.
Scripts are run synchronously;
this means that tinc will temporarily stop processing packets until the called script finishes executing.
This guarantees that scripts will execute in the exact same order as the events that trigger them.
If you need to run commands asynchronously, you have to ensure yourself that they are being run in the background.
Under Windows (not Cygwin), the scripts should have the extension @file{.bat} or @file{.cmd}.
@table @file
@ -1394,6 +1453,7 @@ If it is present it will be executed right after the tinc daemon has been
started and has connected to the virtual network device.
It should be used to set up the corresponding network interface,
but can also be used to start other things.
Under Windows you can use the Network Connections control panel instead of creating this script.
@cindex tinc-down
@ -2226,6 +2286,9 @@ Use the cookie from @var{filename} to authenticate with a running tinc daemon.
If unspecified, the default is
@file{@value{localstatedir}/run/tinc.@var{netname}.pid}.
@item --force
Force some commands to work despite warnings.
@item --help
Display a short reminder of runtime options and commands, then terminate.
@ -2272,6 +2335,7 @@ To set a variable for a specific host, use the notation @var{host}.@var{variable
@cindex add
@item add @var{variable} @var{value}
As above, but without removing any previously existing configuration variables.
If the variable already exists with the given value, nothing happens.
@cindex del
@item del @var{variable} [@var{value}]
@ -2292,16 +2356,16 @@ Export the host configuration file of the local node to standard output.
Export all host configuration files to standard output.
@cindex import
@item import [--force]
@item import
Import host configuration file(s) generated by the tinc export command from standard input.
Already existing host configuration files are not overwritten unless the option --force is used.
@cindex exchange
@item exchange [--force]
@item exchange
The same as export followed by import.
@cindex exchange-all
@item exchange-all [--force]
@item exchange-all
The same as export-all followed by import.
@cindex invite
@ -2373,6 +2437,10 @@ Nodes are colored according to their reachability:
red nodes are unreachable, orange nodes are indirectly reachable, green nodes are directly reachable.
Black nodes are either directly or indirectly reachable, but direct reachability has not been tried yet.
@item dump invitations
Dump a list of outstanding invitations.
The filename of the invitation, as well as the name of the node that is being invited is shown for each invitation.
@cindex info
@item info @var{node} | @var{subnet} | @var{address}
Show information about a particular @var{node}, @var{subnet} or @var{address}.
@ -2415,11 +2483,38 @@ Dump VPN traffic going through the local tinc node in pcap-savefile format to st
from where it can be redirected to a file or piped through a program that can parse it directly,
such as tcpdump.
@cindex network [@var{netname}]
@item network
@cindex network
@item network [@var{netname}]
If @var{netname} is given, switch to that network.
Otherwise, display a list of all networks for which configuration files exist.
@cindex fsck
@item fsck
This will check the configuration files for possible problems,
such as unsafe file permissions, missing executable bit on script,
unknown and obsolete configuration variables, wrong public and/or private keys, and so on.
When problems are found, this will be printed on a line with WARNING or ERROR in front of it.
Most problems must be corrected by the user itself, however in some cases (like file permissions and missing public keys),
tinc will ask if it should fix the problem.
@cindex sign
@item sign [@var{filename}]
Sign a file with the local node's private key.
If no @var{filename} is given, the file is read from standard input.
The signed file is written to standard output.
@cindex verify
@item verify @var{name} [@var{filename}]
Check the signature of a file against a node's public key.
The @var{name} of the node must be given,
or can be "." to check against the local node's public key,
or "*" to allow a signature from any node whose public key is known.
If no @var{filename} is given, the file is read from standard input.
If the verification is succesful, a copy of the input with the signature removed is written to standard output, and the exit code will be zero.
If the verification failed, nothing will be written to standard output, and the exit code will be non-zero.
@end table
@c ==================================================================
@ -2506,6 +2601,159 @@ Quit.
@end table
@c ==================================================================
@node Invitations
@chapter Invitations
Invitations are an easy way to add new nodes to an existing VPN. Invitations
can be created on an existing node using the @code{tinc invite} command, which
generates a relatively short URL which can be given to someone else, who uses
the @code{tinc join} command to automatically set up tinc so it can connect to
the inviting node. The next sections describe how invitations actually work,
and how to further automate the invitations.
@menu
* How invitations work::
* Invitation file format::
* Writing an invitation-created script::
@end menu
@c ==================================================================
@node How invitations work
@section How invitations work
When an invitation is created on a node (which from now on we will call the
server) using the @code{tinc invite} command, an invitation file is created
that contains all the information necessary for the invitee (which we will call
the client) to create its configuration files. The invitation file is stays on
the server, but a URL is generated that has enough information for the client
to contact the server and to retrieve the invitation file. The whole URL is
around 80 characters long and looks like this:
@example
server.example.org:12345/cW1NhLHS-1WPFlcFio8ztYHvewTTKYZp8BjEKg3vbMtDz7w4
@end example
It is composed of four parts:
@example
hostname : port / keyhash cookie
@end example
The hostname and port tell the client how to reach the tinc daemon on the server.
The part after the slash looks like one blob, but is composed of two parts.
The keyhash is the hash of the public key of the server.
The cookie is a shared secret that identifies the client to the server.
When the client connects to the server in order to join the VPN, the client and
server will exchange temporary public keys. The client verifies that the hash
of the server's public key matches the keyhash from the invitation URL. If
not, it will immediately exit with an error. Otherwise, an ECDH exchange will
happen so the client and server can communicate privately with each other. The
client will then present the cookie to the server. The server uses this to
look up the corresponding invitation file it generated earlier. If it exists,
it will send the invitation file to the client. The client will also create a
permanent public key, and send it to the server. After the exchange is
completed, the connection is broken. The server creates a host config file for
the client containing the client's permanent public key, and the client creates
tinc.conf, host config files and possibly a tinc-up script based on the
information in the invitation file.
It is important that the invitation URL is kept secret until it is used; if
another person gets a copy of the invitation URL before the real client runs
the @code{tinc join} command, then that other person can try to join the VPN.
@c ==================================================================
@node Invitation file format
@section Invitation file format
The contents of an invitation file that is generated by the @code{tinc invite}
command looks like this:
@example
Name = client
Netname = vpn
ConnectTo = server
#-------------------------------------#
Name = server
Ed25519PublicKey = augbnwegoij123587...
Address = server.example.com
@end example
The file is basically a concatenation of several host config blocks. Each host
config block starts with @code{Name = ...}. Lines that look like @code{#---#}
are not important, it just makes it easier for humans to read the file.
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 block, the @file{tinc.conf} and @file{hosts/client} files will be
generated; the @code{tinc join} command on the client will automatically
separate statements based on whether they should be in @file{tinc.conf} or in a
host config file. Some statements are special and are treated differently:
@table @asis
@item Netname = <@var{netname}>
This is a hint to the invitee which netname to use for the VPN. It is used if
the invitee did not already specify a netname, and if there is no pre-existing
configuration with the same netname.
@cindex Ifconfig
@item Ifconfig = <@var{address}[/@var{netmask}] | dhcp | dhcp6 | slaac>
This is a hint for generating a @file{tinc-up} script.
If an address is specified, a command will be added to @file{tinc-up} so the VPN interface will be configured to have the given address.
If it is the word "dhcp", a command will be added to start a DHCP client on the VPN interface.
If it is the word dhcpv6, it will be a DHCPv6 client.
If it is "slaac", then it will add commands to enable IPv6 stateless address autoconfiguration.
It is also possible to specify a MAC address, in which case a command will be added to set the MAC address of the VPN interface.
The exact commands added to the @file{tinc-up} script depends on the operating system the client is using.
Multiple Ifconfig statements can be specified, however one should only use one Ifconfig statement per address family.
@cindex Route
@item Route = <@var{address}[/@var{netmask}]> [<@var{gateway}>]
This is a hint for generating a @file{tinc-up} script.
Route statements are similar to Ifconfig statements, but add routes instead of addresses.
These only allow IPv4 and IPv6 routes.
If no gateway address is specified, the route is directed to the VPN interface.
In general, a gateway is only necessary when running tinc in switch mode.
@end table
Subsequent host config blocks are copied verbatim into their respective files
in @file{hosts/}. The invitation file generated by @code{tinc invite} will
normally only contain two blocks; one for the client and one for the server.
@c ==================================================================
@node Writing an invitation-created script
@section Writing an invitation-created script
When an invitation is generated, the "invitation-created" script is called (if
it exists) right after the invitation file is written, but before the URL has
been written to stdout. This allows one to change the invitation file
automatically before the invitation URL is passed to the invitee. Here is an
example shell script that aproximately recreates the default invitation file:
@example
#!/bin/sh
cat >$INVITATION_FILE <<EOF
Name = $NODE
Netname = $NETNAME
ConnectTo = $NAME
#----------------#
EOF
tinc export >>$INVITATION_FILE
@end example
You can add more ConnectTo statements, and change `tinc export` to `tinc
export-all` for example. But you can also use the script to automatically hand
out a Subnet to the invitee. Note that the script doesn't have to be a shell script,
you can use any language, it just has to be executable.
@c ==================================================================
@node Technical information
@chapter Technical information
@ -3076,7 +3324,7 @@ eavesdroppers cannot get and cannot change any information at all from the
packets they can intercept. The encryption algorithm and message authentication
algorithm can be changed in the configuration. The length of the message
authentication codes is also adjustable. The length of the key for the
encryption algorithm is always the default length used by OpenSSL.
encryption algorithm is always the default length used by LibreSSL/OpenSSL.
The SPTPS protocol is described in @ref{Simple Peer-to-Peer Security}.
For comparison, this is how SPTPS UDP packets look:
@ -3103,7 +3351,7 @@ this cannot be changed.
In August 2000, we discovered the existence of a security hole in all versions
of tinc up to and including 1.0pre2. This had to do with the way we exchanged
keys. Since then, we have been working on a new authentication scheme to make
tinc as secure as possible. The current version uses the OpenSSL library and
tinc as secure as possible. The current version uses the LibreSSL or OpenSSL library and
uses strong authentication with RSA keys.
On the 29th of December 2001, Jerome Etienne posted a security analysis of tinc
@ -3278,14 +3526,14 @@ Adding routes to IPv6 subnets:
@section Contact information
@cindex website
Tinc's website is at @url{http://www.tinc-vpn.org/},
Tinc's website is at @url{https://www.tinc-vpn.org/},
this server is located in the Netherlands.
@cindex IRC
We have an IRC channel on the FreeNode and OFTC IRC networks. Connect to
@uref{http://www.freenode.net/, irc.freenode.net}
@uref{https://freenode.net/, irc.freenode.net}
or
@uref{http://www.oftc.net/, irc.oftc.net}
@uref{https://www.oftc.net/, irc.oftc.net}
and join channel #tinc.

View file

@ -8,7 +8,7 @@
.Nd tinc VPN daemon
.Sh SYNOPSIS
.Nm
.Op Fl cdDKnoLRU
.Op Fl cdDKnsoLRU
.Op Fl -config Ns = Ns Ar DIR
.Op Fl -no-detach
.Op Fl -debug Ns Op = Ns Ar LEVEL
@ -16,6 +16,7 @@
.Op Fl -option Ns = Ns Ar [HOST.]KEY=VALUE
.Op Fl -mlock
.Op Fl -logfile Ns Op = Ns Ar FILE
.Op Fl -syslog
.Op Fl -bypass-security
.Op Fl -chroot
.Op Fl -user Ns = Ns Ar USER
@ -88,6 +89,8 @@ If
.Ar FILE
is omitted, the default is
.Pa @localstatedir@/log/tinc. Ns Ar NETNAME Ns Pa .log.
.It Fl s, -syslog
When this option is is set, tinc uses syslog instead of stderr in --no-detach mode.
.It Fl -pidfile Ns = Ns Ar FILENAME
Store a cookie in
.Ar FILENAME
@ -188,7 +191,7 @@ A lot, especially security auditing.
.Sh SEE ALSO
.Xr tinc 8 ,
.Xr tinc.conf 5 ,
.Pa http://www.tinc-vpn.org/ ,
.Pa https://www.tinc-vpn.org/ ,
.Pa http://www.cabal.org/ .
.Pp
The full documentation for tinc is maintained as a Texinfo manual.

View file

@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.14.1 from Makefile.am.
# Makefile.in generated by automake 1.15 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# Copyright (C) 1994-2014 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -15,7 +15,17 @@
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
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 \
?) ;; \
@ -79,18 +89,18 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = gui
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(dist_bin_SCRIPTS)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
$(top_srcdir)/m4/ax_check_link_flag.m4 \
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \
$(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \
$(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \
$(top_srcdir)/configure.ac
$(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 =
@ -144,6 +154,7 @@ am__can_run_installinfo = \
*) (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@
@ -178,6 +189,7 @@ LIBS = @LIBS@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MINIUPNPC_LIBS = @MINIUPNPC_LIBS@
MKDIR_P = @MKDIR_P@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
@ -235,10 +247,12 @@ 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@
@ -260,7 +274,6 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu gui/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu gui/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@ -483,6 +496,8 @@ uninstall-am: uninstall-dist_binSCRIPTS
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.

View file

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python2
# tinc-gui -- GUI for controlling a running tincd
# Copyright (C) 2009-2014 Guus Sliepen <guus@tinc-vpn.org>
@ -20,11 +20,12 @@
import string
import socket
import wx
import sys
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
@ -32,7 +33,6 @@ if platform.system() == 'Windows':
import _winreg
# Classes to interface with a running tinc daemon
REQ_STOP = 0
REQ_RELOAD = 1
REQ_RESTART = 2
@ -51,65 +51,120 @@ ID = 0
ACK = 4
CONTROL = 18
class Node:
def parse(self, args):
class Node(object):
def __init__(self, args):
self.name = args[0]
self.address = args[1]
self.port = args[3]
self.cipher = int(args[4])
self.digest = int(args[5])
self.maclength = int(args[6])
self.compression = int(args[7])
self.options = int(args[8], 0x10)
self.status = int(args[9], 0x10)
self.nexthop = args[10]
self.via = args[11]
self.distance = int(args[12])
self.pmtu = int(args[13])
self.minmtu = int(args[14])
self.maxmtu = int(args[15])
self.last_state_change = float(args[16])
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:
def parse(self, args):
self.fr = args[0]
self.to = args[1]
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:
def parse(self, args):
class Subnet(object):
def __init__(self, args):
if args[0].find('#') >= 0:
(address, self.weight) = args[0].split('#', 1)
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)
self.address, self.prefixlen = address.split('/', 1)
else:
self.address = address
self.prefixlen = '48'
self.owner = args[1]
class Connection:
def parse(self, args):
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 = 123
class VPN:
confdir = '/etc/tinc'
piddir = '/var/run/'
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
@ -118,10 +173,10 @@ class VPN:
f.close()
# check if there is a UNIX socket as well
if self.pidfile.endswith(".pid"):
unixfile = self.pidfile.replace(".pid", ".socket");
if self.pidfile.endswith('.pid'):
unixfile = self.pidfile.replace('.pid', '.socket');
else:
unixfile = self.pidfile + ".socket";
unixfile = self.pidfile + '.socket';
if os.path.exists(unixfile):
# use it if it exists
@ -146,14 +201,11 @@ class VPN:
self.sf.flush()
resp = string.split(self.sf.readline())
self.port = info[4]
self.nodes = {}
self.edges = {}
self.subnets = {}
self.connections = {}
self.refresh()
def refresh(self):
self.sf.write('18 3\r\n18 4\r\n18 5\r\n18 6\r\n')
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():
@ -174,22 +226,19 @@ class VPN:
if resp[1] == '3':
if len(resp) < 19:
continue
node = self.nodes.get(resp[2]) or Node()
node.parse(resp[2:])
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()
edge.parse(resp[2:])
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()
subnet.parse(resp[2:])
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)":
@ -198,8 +247,7 @@ class VPN:
elif resp[1] == '6':
if len(resp) < 9:
break
connection = self.connections.get((resp[2], resp[3], resp[5])) or Connection()
connection.parse(resp[2:])
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:
@ -233,85 +281,12 @@ class VPN:
self.sf.flush()
resp = string.split(self.sf.readline())
def debug(self, level = -1):
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])
def __init__(self, netname = None, pidfile = None):
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)
VPN.confdir = _winreg.QueryValue(key, None)
except WindowsError:
pass
if netname:
self.netname = netname
self.confbase = os.path.join(VPN.confdir, netname)
else:
self.confbase = VPN.confdir
self.tincconf = os.path.join(self.confbase, 'tinc.conf')
if pidfile != 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(VPN.piddir, 'tinc.' + netname + '.pid')
else:
self.pidfile = os.path.join(VPN.piddir, 'tinc.pid')
# GUI starts here
argv0 = sys.argv[0]
del sys.argv[0]
netname = None
pidfile = None
def usage(exitcode = 0):
print('Usage: ' + argv0 + ' [options]')
print('\nValid options are:')
print(' -n, --net=NETNAME Connect to net NETNAME.')
print(' --pidfile=FILENAME Read control cookie from FILENAME.')
print(' --help Display this help and exit.')
print('\nReport bugs to tinc@tinc-vpn.org.')
sys.exit(exitcode)
while sys.argv:
if sys.argv[0] in ('-n', '--net'):
del sys.argv[0]
netname = sys.argv[0]
elif sys.argv[0] in ('--pidfile'):
del sys.argv[0]
pidfile = sys.argv[0]
elif sys.argv[0] in ('--help'):
usage(0)
else:
print(argv0 + ': unrecognized option \'' + sys.argv[0] + '\'')
usage(1)
del sys.argv[0]
if netname == None:
netname = os.getenv("NETNAME")
if netname == ".":
netname = None
vpn = VPN(netname, pidfile)
vpn.connect()
class SuperListCtrl(wx.ListCtrl, ColumnSorterMixin, ListCtrlAutoWidthMixin):
def __init__(self, parent, style):
@ -324,12 +299,12 @@ class SuperListCtrl(wx.ListCtrl, ColumnSorterMixin, ListCtrlAutoWidthMixin):
class SettingsPage(wx.Panel):
def OnDebugLevel(self, event):
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 = wx.FlexGridSizer(cols=2)
grid.AddGrowableCol(1, 1)
namelabel = wx.StaticText(self, -1, 'Name:')
@ -343,18 +318,19 @@ class SettingsPage(wx.Panel):
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.OnDebugLevel)
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'])
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)
@ -378,13 +354,13 @@ class ConnectionsPage(wx.Panel):
disconnect = wx.MenuItem(self, -1, 'Disconnect')
self.AppendItem(disconnect)
self.Bind(wx.EVT_MENU, self.OnDisconnect, id=disconnect.GetId())
self.Bind(wx.EVT_MENU, self.on_disconnect, id=disconnect.GetId())
def OnDisconnect(self, event):
def on_disconnect(self, event):
vpn.disconnect(self.item[0])
def OnContext(self, event):
i = event.GetIndex()
def on_context(self, event):
idx = event.GetIndex()
self.PopupMenu(self.ContextMenu(self.list.itemDataMap[event.GetIndex()]), event.GetPosition())
def refresh(self):
@ -401,8 +377,9 @@ class ConnectionsPage(wx.Panel):
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.OnContext)
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
@ -411,20 +388,21 @@ class ConnectionsPage(wx.Panel):
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(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')
@ -466,7 +444,9 @@ class NodesPage(wx.Panel):
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.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
@ -475,6 +455,7 @@ class NodesPage(wx.Panel):
self.list.SortListItems(sortstate[0], sortstate[1])
class EdgesPage(wx.Panel):
def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id)
@ -498,15 +479,15 @@ class EdgesPage(wx.Panel):
for key, edge in vpn.edges.items():
if self.list.GetItemCount() <= i:
self.list.InsertStringItem(i, edge.fr)
self.list.InsertStringItem(i, edge.source)
else:
self.list.SetStringItem(i, 0, edge.fr)
self.list.SetStringItem(i, 1, edge.to)
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.fr, edge.to, edge.address, edge.port, edge.options, 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
@ -515,6 +496,7 @@ class EdgesPage(wx.Panel):
self.list.SortListItems(sortstate[0], sortstate[1])
class SubnetsPage(wx.Panel):
def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id)
@ -548,14 +530,17 @@ class SubnetsPage(wx.Panel):
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)
@ -568,55 +553,82 @@ class NetPage(wx.Notebook):
self.status = StatusPage(self, id)
self.AddPage(self.settings, 'Settings')
#self.AddPage(self.status, 'Status')
# 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')
# self.AddPage(self.graph, 'Graph')
class MainWindow(wx.Frame):
def OnQuit(self, event):
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 OnTimer(self, event):
def on_timer(self, event):
vpn.refresh()
self.np.nodes.refresh()
self.np.subnets.refresh()
self.np.edges.refresh()
self.np.connections.refresh()
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title)
menubar = wx.MenuBar()
file = wx.Menu()
file.Append(1, '&Quit\tCtrl-X', 'Quit tinc GUI')
menubar.Append(file, '&File')
def main(netname, pidfile):
global vpn, app
#nb = wx.Notebook(self, -1)
#nb.SetPadding((0, 0))
self.np = NetPage(self, -1)
#nb.AddPage(np, 'VPN')
if netname is None:
netname = os.getenv('NETNAME')
self.timer = wx.Timer(self, -1)
self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
self.timer.Start(1000)
self.Bind(wx.EVT_MENU, self.OnQuit, id=1)
self.SetMenuBar(menubar)
self.Show()
vpn = VPN(netname, pidfile)
vpn.connect()
app = wx.App()
mw = MainWindow(None, -1, 'Tinc GUI')
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)
"""
def OnTaskBarIcon(event):
mw.Raise()
"""
app.MainLoop()
vpn.close()
"""
icon = wx.Icon("tincgui.ico", wx.BITMAP_TYPE_PNG)
taskbaricon = wx.TaskBarIcon()
taskbaricon.SetIcon(icon, 'Tinc GUI')
wx.EVT_TASKBAR_RIGHT_UP(taskbaricon, OnTaskBarIcon)
"""
app.MainLoop()
vpn.close()
if __name__ == '__main__':
argparser = ArgumentParser(epilog='Report bugs to tinc@tinc-vpn.org.')
argparser.add_argument('-n', '--net', metavar='NETNAME', dest='netname', help='Connect to net NETNAME')
argparser.add_argument('-p', '--pidfile', help='Path to the pid file (containing the controlcookie)')
options = argparser.parse_args()
main(options.netname, options.pidfile)

View file

@ -1,7 +1,7 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2011-11-20.07; # UTC
scriptversion=2014-09-12.12; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
@ -41,19 +41,15 @@ scriptversion=2011-11-20.07; # UTC
# This script is compatible with the BSD install script, but was written
# from scratch.
tab=' '
nl='
'
IFS=" "" $nl"
IFS=" $tab$nl"
# set DOITPROG to echo to test this script
# Set DOITPROG to "echo" to test this script.
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit=${DOITPROG-}
if test -z "$doit"; then
doit_exec=exec
else
doit_exec=$doit
fi
doit_exec=${doit:-exec}
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
@ -68,17 +64,6 @@ mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_glob='?'
initialize_posix_glob='
test "$posix_glob" != "?" || {
if (set -f) 2>/dev/null; then
posix_glob=
else
posix_glob=:
fi
}
'
posix_mkdir=
# Desired mode of installed file.
@ -97,7 +82,7 @@ dir_arg=
dst_arg=
copy_on_change=false
no_target_directory=
is_target_a_directory=possibly
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
@ -143,8 +128,7 @@ while test $# -ne 0; do
-m) mode=$2
case $mode in
*' '* | *' '* | *'
'* | *'*'* | *'?'* | *'['*)
*' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
@ -155,14 +139,16 @@ while test $# -ne 0; do
-s) stripcmd=$stripprog;;
-t) dst_arg=$2
-t)
is_target_a_directory=always
dst_arg=$2
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
shift;;
-T) no_target_directory=true;;
-T) is_target_a_directory=never;;
--version) echo "$0 $scriptversion"; exit $?;;
@ -177,6 +163,16 @@ while test $# -ne 0; do
shift
done
# We allow the use of options -d and -T together, by making -d
# take the precedence; this is for compatibility with GNU install.
if test -n "$dir_arg"; then
if test -n "$dst_arg"; then
echo "$0: target directory not allowed when installing a directory." >&2
exit 1
fi
fi
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
@ -207,6 +203,15 @@ if test $# -eq 0; then
exit 0
fi
if test -z "$dir_arg"; then
if test $# -gt 1 || test "$is_target_a_directory" = always; then
if test ! -d "$dst_arg"; then
echo "$0: $dst_arg: Is not a directory." >&2
exit 1
fi
fi
fi
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
@ -269,7 +274,7 @@ do
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test -n "$no_target_directory"; then
if test "$is_target_a_directory" = never; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
@ -277,33 +282,7 @@ do
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
# Prefer dirname, but fall back on a substitute if dirname fails.
dstdir=`
(dirname "$dst") 2>/dev/null ||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$dst" : 'X\(//\)[^/]' \| \
X"$dst" : 'X\(//\)$' \| \
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
echo X"$dst" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'
`
dstdir=`dirname "$dst"`
test -d "$dstdir"
dstdir_status=$?
fi
@ -345,34 +324,41 @@ do
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
# $RANDOM is not portable (e.g. dash); use it when possible to
# lower collision chance
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/d" "$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
# create the $tmpdir first (and fail if unsuccessful) to make sure
# that nobody tries to guess the $tmpdir name.
if (umask $mkdir_umask &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
$mkdirprog $mkdir_mode "$tmpdir" &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
test_tmpdir="$tmpdir/a"
ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
$mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/d" "$tmpdir"
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
fi
trap '' 0;;
esac;;
@ -396,14 +382,12 @@ do
*) prefix='';;
esac
eval "$initialize_posix_glob"
oIFS=$IFS
IFS=/
$posix_glob set -f
set -f
set fnord $dstdir
shift
$posix_glob set +f
set +f
IFS=$oIFS
prefixes=
@ -474,13 +458,10 @@ do
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
eval "$initialize_posix_glob" &&
$posix_glob set -f &&
set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
$posix_glob set +f &&
set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then

View file

@ -1,4 +0,0 @@
## Process this file with automake to produce Makefile.in -*-Makefile-*-
EXTRA_DIST = README *.m4

View file

@ -1,8 +0,0 @@
These files are used by a program called aclocal (part of the GNU automake
package). aclocal uses these files to create aclocal.m4 which is in turn
used by autoconf to create the configure script at the the top level in
this distribution.
The Makefile.am file in this directory is automatically generated
from the template file, Makefile.am.in. The generation will fail
if you don't have all the right tools.

View file

@ -9,8 +9,8 @@ AC_DEFUN([tinc_ATTRIBUTE],
CFLAGS="$CFLAGS -Wall -Werror"
AC_COMPILE_IFELSE(
[AC_LANG_SOURCE(
[void test(void) __attribute__ (($1));
void test(void) { return; }
[void *test(void) __attribute__ (($1));
void *test(void) { return (void *)0; }
],
)],
[tinc_cv_attribute_$1=yes],

40
m4/miniupnpc.m4 Normal file
View file

@ -0,0 +1,40 @@
dnl Check to find the miniupnpc headers/libraries
AC_DEFUN([tinc_MINIUPNPC],
[
AC_ARG_ENABLE([miniupnpc],
AS_HELP_STRING([--enable-miniupnpc], [enable miniupnpc support]))
AS_IF([test "x$enable_miniupnpc" = "xyes"], [
AC_DEFINE(HAVE_MINIUPNPC, 1, [have miniupnpc support])
AC_ARG_WITH(miniupnpc,
AS_HELP_STRING([--with-miniupnpc=DIR], [miniupnpc base directory, or:]),
[miniupnpc="$withval"
CPPFLAGS="$CPPFLAGS -I$withval/include"
LDFLAGS="$LDFLAGS -L$withval/lib"]
)
AC_ARG_WITH(miniupnpc-include,
AS_HELP_STRING([--with-miniupnpc-include=DIR], [miniupnpc headers directory]),
[miniupnpc_include="$withval"
CPPFLAGS="$CPPFLAGS -I$withval"]
)
AC_ARG_WITH(miniupnpc-lib,
AS_HELP_STRING([--with-miniupnpc-lib=DIR], [miniupnpc library directory]),
[miniupnpc_lib="$withval"
LDFLAGS="$LDFLAGS -L$withval"]
)
AC_CHECK_HEADERS(miniupnpc/miniupnpc.h,
[],
[AC_MSG_ERROR("miniupnpc header files not found."); break]
)
AC_CHECK_LIB(miniupnpc, upnpDiscover,
[MINIUPNPC_LIBS="$LIBS -lminiupnpc"],
[AC_MSG_ERROR("miniupnpc libraries not found.")]
)
])
AC_SUBST(MINIUPNPC_LIBS)
])

View file

@ -1,4 +1,4 @@
dnl Check to find the OpenSSL headers/libraries
dnl Check to find the LibreSSL/OpenSSL headers/libraries
AC_DEFUN([tinc_OPENSSL],
[
@ -10,47 +10,47 @@ AC_DEFUN([tinc_OPENSSL],
[],
[AC_CHECK_LIB(dl, dlopen,
[LIBS="$LIBS -ldl"],
[AC_MSG_ERROR([OpenSSL depends on libdl.]); break]
[AC_MSG_ERROR([LibreSSL/OpenSSL depends on libdl.]); break]
)]
)
;;
esac
AC_ARG_WITH(openssl,
AS_HELP_STRING([--with-openssl=DIR], [OpenSSL base directory, or:]),
AS_HELP_STRING([--with-openssl=DIR], [LibreSSL/OpenSSL base directory, or:]),
[openssl="$withval"
CPPFLAGS="$CPPFLAGS -I$withval/include"
LDFLAGS="$LDFLAGS -L$withval/lib"]
)
AC_ARG_WITH(openssl-include,
AS_HELP_STRING([--with-openssl-include=DIR], [OpenSSL headers directory (without trailing /openssl)]),
AS_HELP_STRING([--with-openssl-include=DIR], [LibreSSL/OpenSSL headers directory (without trailing /openssl)]),
[openssl_include="$withval"
CPPFLAGS="$CPPFLAGS -I$withval"]
)
AC_ARG_WITH(openssl-lib,
AS_HELP_STRING([--with-openssl-lib=DIR], [OpenSSL library directory]),
AS_HELP_STRING([--with-openssl-lib=DIR], [LibreSSL/OpenSSL library directory]),
[openssl_lib="$withval"
LDFLAGS="$LDFLAGS -L$withval"]
)
AC_CHECK_HEADERS([openssl/evp.h openssl/rsa.h openssl/rand.h openssl/err.h openssl/sha.h openssl/pem.h openssl/engine.h],
[],
[AC_MSG_ERROR([OpenSSL header files not found.]); break]
[AC_MSG_ERROR([LibreSSL/OpenSSL header files not found.]); break]
)
AC_CHECK_LIB(crypto, EVP_EncryptInit_ex,
[LIBS="-lcrypto $LIBS"],
[AC_MSG_ERROR([OpenSSL libraries not found.])]
[AC_MSG_ERROR([LibreSSL/OpenSSL libraries not found.])]
)
AC_CHECK_FUNCS([RAND_status EVP_EncryptInit_ex], ,
[AC_MSG_ERROR([Missing 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], ,
[AC_MSG_ERROR([Missing 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>]
)
])

View file

@ -3,7 +3,7 @@
scriptversion=2013-10-28.13; # UTC
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify

View file

@ -2,16 +2,25 @@
sbin_PROGRAMS = tincd tinc sptps_test sptps_keypair
## Make sure version.c is always rebuilt
.PHONY: version.c
version.c:
CLEANFILES = version_git.h
.PHONY: version-stamp
version-stamp:
version_git.h: version-stamp
$(AM_V_GEN)echo >$@
@-(cd $(srcdir) && git describe 2>/dev/null >/dev/null) && echo '#define GIT_DESCRIPTION "'`(cd $(srcdir) && git describe) | sed 's/release-//'`'"' >$@ ||:
${srcdir}/version.c: version_git.h
## Now a hack to appease some versions of BSD make that don't understand that "./foo" is the same as "foo".
if BSD
version.c: ${srcdir}/version.c
endif
if LINUX
sbin_PROGRAMS += sptps_speed
endif
DEFAULT_INCLUDES =
ed25519_SOURCES = \
ed25519/add_scalar.c \
ed25519/ed25519.h \
@ -49,11 +58,6 @@ tincd_SOURCES = \
edge.c edge.h \
ethernet.h \
event.c event.h \
fake-gai-errnos.h \
fake-getaddrinfo.c fake-getaddrinfo.h \
fake-getnameinfo.c fake-getnameinfo.h \
getopt.c getopt.h \
getopt1.c \
graph.c graph.h \
hash.c hash.h \
have.h \
@ -92,13 +96,15 @@ tincd_SOURCES = \
utils.c utils.h \
xalloc.h \
version.c version.h \
ed25519/ecdh.c \
ed25519/ecdsa.c \
$(ed25519_SOURCES) \
$(chacha_poly1305_SOURCES)
tinc_SOURCES = \
dropin.c dropin.h \
getopt.c getopt.h \
getopt1.c \
fsck.c fsck.h \
ifconfig.c ifconfig.h \
info.c info.h \
invitation.c invitation.h \
list.c list.h \
@ -111,6 +117,9 @@ tinc_SOURCES = \
top.c top.h \
utils.c utils.h \
version.c version.h \
ed25519/ecdh.c \
ed25519/ecdsa.c \
ed25519/ecdsagen.c \
$(ed25519_SOURCES) \
$(chacha_poly1305_SOURCES)
@ -119,12 +128,15 @@ sptps_test_SOURCES = \
sptps.c sptps.h \
sptps_test.c \
utils.c utils.h \
ed25519/ecdh.c \
ed25519/ecdsa.c \
$(ed25519_SOURCES) \
$(chacha_poly1305_SOURCES)
sptps_keypair_SOURCES = \
sptps_keypair.c \
utils.c utils.h \
ed25519/ecdsagen.c \
$(ed25519_SOURCES)
sptps_speed_SOURCES = \
@ -132,11 +144,29 @@ sptps_speed_SOURCES = \
sptps.c sptps.h \
sptps_speed.c \
utils.c utils.h \
ed25519/ecdh.c \
ed25519/ecdsa.c \
ed25519/ecdsagen.c \
$(ed25519_SOURCES) \
$(chacha_poly1305_SOURCES)
## Conditionally compile device drivers
if !GETOPT
tincd_SOURCES += \
getopt.c getopt.h \
getopt1.c
tinc_SOURCES += \
getopt.c getopt.h \
getopt1.c
sptps_test_SOURCES += \
getopt.c getopt.h \
getopt1.c
sptps_keypair_SOURCES += \
getopt.c getopt.h \
getopt1.c
endif
if LINUX
tincd_SOURCES += linux/device.c
endif
@ -173,54 +203,37 @@ tincd_SOURCES += \
openssl/cipher.c \
openssl/crypto.c \
openssl/digest.c openssl/digest.h \
ed25519/ecdh.c \
ed25519/ecdsa.c \
openssl/prf.c \
openssl/rsa.c
tinc_SOURCES += \
openssl/cipher.c \
openssl/crypto.c \
openssl/digest.c openssl/digest.h \
ed25519/ecdh.c \
ed25519/ecdsa.c \
ed25519/ecdsagen.c \
openssl/prf.c \
openssl/rsa.c \
openssl/rsagen.c
sptps_test_SOURCES += \
openssl/crypto.c \
openssl/digest.c openssl/digest.h \
ed25519/ecdh.c \
ed25519/ecdsa.c \
openssl/prf.c
sptps_keypair_SOURCES += \
openssl/crypto.c \
ed25519/ecdsagen.c
openssl/crypto.c
sptps_speed_SOURCES += \
openssl/crypto.c \
openssl/digest.c openssl/digest.h \
ed25519/ecdh.c \
ed25519/ecdsa.c \
ed25519/ecdsagen.c \
openssl/prf.c
endif
else
if GCRYPT
tincd_SOURCES += \
gcrypt/cipher.c \
gcrypt/crypto.c \
gcrypt/digest.c gcrypt/digest.h \
gcrypt/ecdh.c \
gcrypt/ecdsa.c \
gcrypt/prf.c \
gcrypt/rsa.c
tinc_SOURCES += \
gcrypt/cipher.c \
gcrypt/crypto.c \
gcrypt/digest.c gcrypt/digest.h \
gcrypt/ecdh.c \
gcrypt/ecdsa.c \
gcrypt/ecdsagen.c \
gcrypt/prf.c \
gcrypt/rsa.c \
gcrypt/rsagen.c
@ -228,18 +241,44 @@ sptps_test_SOURCES += \
gcrypt/cipher.c \
gcrypt/crypto.c \
gcrypt/digest.c gcrypt/digest.h \
gcrypt/ecdh.c \
gcrypt/ecdsa.c \
gcrypt/prf.c
sptps_keypair_SOURCES += \
openssl/crypto.c
sptps_speed_SOURCES += \
openssl/crypto.c \
openssl/digest.c openssl/digest.h \
openssl/prf.c
else
tincd_SOURCES += \
nolegacy/crypto.c \
nolegacy/prf.c
tinc_SOURCES += \
nolegacy/crypto.c \
nolegacy/prf.c
sptps_test_SOURCES += \
nolegacy/crypto.c \
nolegacy/prf.c
sptps_keypair_SOURCES += \
nolegacy/crypto.c
sptps_speed_SOURCES += \
nolegacy/crypto.c \
nolegacy/prf.c
endif
endif
if MINIUPNPC
tincd_SOURCES += upnp.h upnp.c
tincd_LDADD = $(MINIUPNPC_LIBS)
tincd_LDFLAGS = -pthread
endif
tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS)
sptps_speed_LDADD = -lrt
LIBS = @LIBS@
LIBS = @LIBS@ -lm
if TUNEMU
LIBS += -lpcap
endif
AM_CFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DSBINDIR=\"$(sbindir)\"
AM_CFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DSBINDIR=\"$(sbindir)\" -iquote.

View file

@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.14.1 from Makefile.am.
# Makefile.in generated by automake 1.15 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# Copyright (C) 1994-2014 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -15,7 +15,17 @@
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
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 \
?) ;; \
@ -81,95 +91,120 @@ host_triplet = @host@
sbin_PROGRAMS = tincd$(EXEEXT) tinc$(EXEEXT) sptps_test$(EXEEXT) \
sptps_keypair$(EXEEXT) $(am__EXEEXT_1)
@LINUX_TRUE@am__append_1 = sptps_speed
@LINUX_TRUE@am__append_2 = linux/device.c
@BSD_TRUE@am__append_3 = bsd/device.c
@BSD_TRUE@@TUNEMU_TRUE@am__append_4 = bsd/tunemu.c bsd/tunemu.h
@SOLARIS_TRUE@am__append_5 = solaris/device.c
@MINGW_TRUE@am__append_6 = mingw/device.c mingw/common.h
@CYGWIN_TRUE@am__append_7 = cygwin/device.c
@UML_TRUE@am__append_8 = uml_device.c
@VDE_TRUE@am__append_9 = vde_device.c
@OPENSSL_TRUE@am__append_10 = \
@GETOPT_FALSE@am__append_2 = \
@GETOPT_FALSE@ getopt.c getopt.h \
@GETOPT_FALSE@ getopt1.c
@GETOPT_FALSE@am__append_3 = \
@GETOPT_FALSE@ getopt.c getopt.h \
@GETOPT_FALSE@ getopt1.c
@GETOPT_FALSE@am__append_4 = \
@GETOPT_FALSE@ getopt.c getopt.h \
@GETOPT_FALSE@ getopt1.c
@GETOPT_FALSE@am__append_5 = \
@GETOPT_FALSE@ getopt.c getopt.h \
@GETOPT_FALSE@ getopt1.c
@LINUX_TRUE@am__append_6 = linux/device.c
@BSD_TRUE@am__append_7 = bsd/device.c
@BSD_TRUE@@TUNEMU_TRUE@am__append_8 = bsd/tunemu.c bsd/tunemu.h
@SOLARIS_TRUE@am__append_9 = solaris/device.c
@MINGW_TRUE@am__append_10 = mingw/device.c mingw/common.h
@CYGWIN_TRUE@am__append_11 = cygwin/device.c
@UML_TRUE@am__append_12 = uml_device.c
@VDE_TRUE@am__append_13 = vde_device.c
@OPENSSL_TRUE@am__append_14 = \
@OPENSSL_TRUE@ openssl/cipher.c \
@OPENSSL_TRUE@ openssl/crypto.c \
@OPENSSL_TRUE@ openssl/digest.c openssl/digest.h \
@OPENSSL_TRUE@ ed25519/ecdh.c \
@OPENSSL_TRUE@ ed25519/ecdsa.c \
@OPENSSL_TRUE@ openssl/prf.c \
@OPENSSL_TRUE@ openssl/rsa.c
@OPENSSL_TRUE@am__append_11 = \
@OPENSSL_TRUE@am__append_15 = \
@OPENSSL_TRUE@ openssl/cipher.c \
@OPENSSL_TRUE@ openssl/crypto.c \
@OPENSSL_TRUE@ openssl/digest.c openssl/digest.h \
@OPENSSL_TRUE@ ed25519/ecdh.c \
@OPENSSL_TRUE@ ed25519/ecdsa.c \
@OPENSSL_TRUE@ ed25519/ecdsagen.c \
@OPENSSL_TRUE@ openssl/prf.c \
@OPENSSL_TRUE@ openssl/rsa.c \
@OPENSSL_TRUE@ openssl/rsagen.c
@OPENSSL_TRUE@am__append_12 = \
@OPENSSL_TRUE@am__append_16 = \
@OPENSSL_TRUE@ openssl/crypto.c \
@OPENSSL_TRUE@ openssl/digest.c openssl/digest.h \
@OPENSSL_TRUE@ ed25519/ecdh.c \
@OPENSSL_TRUE@ ed25519/ecdsa.c \
@OPENSSL_TRUE@ openssl/prf.c
@OPENSSL_TRUE@am__append_13 = \
@OPENSSL_TRUE@ openssl/crypto.c \
@OPENSSL_TRUE@ ed25519/ecdsagen.c
@OPENSSL_TRUE@am__append_17 = \
@OPENSSL_TRUE@ openssl/crypto.c
@OPENSSL_TRUE@am__append_14 = \
@OPENSSL_TRUE@am__append_18 = \
@OPENSSL_TRUE@ openssl/crypto.c \
@OPENSSL_TRUE@ openssl/digest.c openssl/digest.h \
@OPENSSL_TRUE@ ed25519/ecdh.c \
@OPENSSL_TRUE@ ed25519/ecdsa.c \
@OPENSSL_TRUE@ ed25519/ecdsagen.c \
@OPENSSL_TRUE@ openssl/prf.c
@GCRYPT_TRUE@am__append_15 = \
@GCRYPT_TRUE@ gcrypt/cipher.c \
@GCRYPT_TRUE@ gcrypt/crypto.c \
@GCRYPT_TRUE@ gcrypt/digest.c gcrypt/digest.h \
@GCRYPT_TRUE@ gcrypt/ecdh.c \
@GCRYPT_TRUE@ gcrypt/ecdsa.c \
@GCRYPT_TRUE@ gcrypt/prf.c \
@GCRYPT_TRUE@ gcrypt/rsa.c
@GCRYPT_TRUE@@OPENSSL_FALSE@am__append_19 = \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/cipher.c \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/crypto.c \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/digest.c gcrypt/digest.h \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/prf.c \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/rsa.c
@GCRYPT_TRUE@am__append_16 = \
@GCRYPT_TRUE@ gcrypt/cipher.c \
@GCRYPT_TRUE@ gcrypt/crypto.c \
@GCRYPT_TRUE@ gcrypt/digest.c gcrypt/digest.h \
@GCRYPT_TRUE@ gcrypt/ecdh.c \
@GCRYPT_TRUE@ gcrypt/ecdsa.c \
@GCRYPT_TRUE@ gcrypt/ecdsagen.c \
@GCRYPT_TRUE@ gcrypt/prf.c \
@GCRYPT_TRUE@ gcrypt/rsa.c \
@GCRYPT_TRUE@ gcrypt/rsagen.c
@GCRYPT_TRUE@@OPENSSL_FALSE@am__append_20 = \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/cipher.c \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/crypto.c \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/digest.c gcrypt/digest.h \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/prf.c \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/rsa.c \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/rsagen.c
@GCRYPT_TRUE@am__append_17 = \
@GCRYPT_TRUE@ gcrypt/cipher.c \
@GCRYPT_TRUE@ gcrypt/crypto.c \
@GCRYPT_TRUE@ gcrypt/digest.c gcrypt/digest.h \
@GCRYPT_TRUE@ gcrypt/ecdh.c \
@GCRYPT_TRUE@ gcrypt/ecdsa.c \
@GCRYPT_TRUE@ gcrypt/prf.c
@GCRYPT_TRUE@@OPENSSL_FALSE@am__append_21 = \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/cipher.c \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/crypto.c \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/digest.c gcrypt/digest.h \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/prf.c
@TUNEMU_TRUE@am__append_18 = -lpcap
@GCRYPT_TRUE@@OPENSSL_FALSE@am__append_22 = \
@GCRYPT_TRUE@@OPENSSL_FALSE@ openssl/crypto.c
@GCRYPT_TRUE@@OPENSSL_FALSE@am__append_23 = \
@GCRYPT_TRUE@@OPENSSL_FALSE@ openssl/crypto.c \
@GCRYPT_TRUE@@OPENSSL_FALSE@ openssl/digest.c openssl/digest.h \
@GCRYPT_TRUE@@OPENSSL_FALSE@ openssl/prf.c
@GCRYPT_FALSE@@OPENSSL_FALSE@am__append_24 = \
@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/crypto.c \
@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/prf.c
@GCRYPT_FALSE@@OPENSSL_FALSE@am__append_25 = \
@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/crypto.c \
@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/prf.c
@GCRYPT_FALSE@@OPENSSL_FALSE@am__append_26 = \
@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/crypto.c \
@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/prf.c
@GCRYPT_FALSE@@OPENSSL_FALSE@am__append_27 = \
@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/crypto.c
@GCRYPT_FALSE@@OPENSSL_FALSE@am__append_28 = \
@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/crypto.c \
@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/prf.c
@MINIUPNPC_TRUE@am__append_29 = upnp.h upnp.c
@TUNEMU_TRUE@am__append_30 = -lpcap
subdir = src
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/depcomp
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
$(top_srcdir)/m4/ax_check_link_flag.m4 \
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \
$(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \
$(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \
$(top_srcdir)/configure.ac
$(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 $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
@ -178,78 +213,91 @@ CONFIG_CLEAN_VPATH_FILES =
am__installdirs = "$(DESTDIR)$(sbindir)"
PROGRAMS = $(sbin_PROGRAMS)
am__sptps_keypair_SOURCES_DIST = sptps_keypair.c utils.c utils.h \
ed25519/add_scalar.c ed25519/ed25519.h ed25519/fe.c \
ed25519/fe.h ed25519/fixedint.h ed25519/ge.c ed25519/ge.h \
ed25519/key_exchange.c ed25519/keypair.c \
ed25519/ecdsagen.c ed25519/add_scalar.c ed25519/ed25519.h \
ed25519/fe.c ed25519/fe.h ed25519/fixedint.h ed25519/ge.c \
ed25519/ge.h ed25519/key_exchange.c ed25519/keypair.c \
ed25519/precomp_data.h ed25519/sc.c ed25519/sc.h \
ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \
ed25519/verify.c openssl/crypto.c ed25519/ecdsagen.c
ed25519/verify.c getopt.c getopt.h getopt1.c openssl/crypto.c \
nolegacy/crypto.c
am__dirstamp = $(am__leading_dot)dirstamp
am__objects_1 = ed25519/add_scalar.$(OBJEXT) ed25519/fe.$(OBJEXT) \
ed25519/ge.$(OBJEXT) ed25519/key_exchange.$(OBJEXT) \
ed25519/keypair.$(OBJEXT) ed25519/sc.$(OBJEXT) \
ed25519/sha512.$(OBJEXT) ed25519/sign.$(OBJEXT) \
ed25519/verify.$(OBJEXT)
@OPENSSL_TRUE@am__objects_2 = openssl/crypto.$(OBJEXT) \
@OPENSSL_TRUE@ ed25519/ecdsagen.$(OBJEXT)
@GETOPT_FALSE@am__objects_2 = getopt.$(OBJEXT) getopt1.$(OBJEXT)
@OPENSSL_TRUE@am__objects_3 = openssl/crypto.$(OBJEXT)
@GCRYPT_TRUE@@OPENSSL_FALSE@am__objects_4 = openssl/crypto.$(OBJEXT)
@GCRYPT_FALSE@@OPENSSL_FALSE@am__objects_5 = \
@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/crypto.$(OBJEXT)
am_sptps_keypair_OBJECTS = sptps_keypair.$(OBJEXT) utils.$(OBJEXT) \
$(am__objects_1) $(am__objects_2)
ed25519/ecdsagen.$(OBJEXT) $(am__objects_1) $(am__objects_2) \
$(am__objects_3) $(am__objects_4) $(am__objects_5)
sptps_keypair_OBJECTS = $(am_sptps_keypair_OBJECTS)
sptps_keypair_LDADD = $(LDADD)
am__sptps_speed_SOURCES_DIST = logger.c logger.h sptps.c sptps.h \
sptps_speed.c utils.c utils.h ed25519/add_scalar.c \
ed25519/ed25519.h ed25519/fe.c ed25519/fe.h ed25519/fixedint.h \
ed25519/ge.c ed25519/ge.h ed25519/key_exchange.c \
ed25519/keypair.c ed25519/precomp_data.h ed25519/sc.c \
ed25519/sc.h ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \
sptps_speed.c utils.c utils.h ed25519/ecdh.c ed25519/ecdsa.c \
ed25519/ecdsagen.c ed25519/add_scalar.c ed25519/ed25519.h \
ed25519/fe.c ed25519/fe.h ed25519/fixedint.h ed25519/ge.c \
ed25519/ge.h ed25519/key_exchange.c ed25519/keypair.c \
ed25519/precomp_data.h ed25519/sc.c ed25519/sc.h \
ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \
ed25519/verify.c chacha-poly1305/chacha.c \
chacha-poly1305/chacha.h chacha-poly1305/chacha-poly1305.c \
chacha-poly1305/chacha-poly1305.h chacha-poly1305/poly1305.c \
chacha-poly1305/poly1305.h openssl/crypto.c openssl/digest.c \
openssl/digest.h ed25519/ecdh.c ed25519/ecdsa.c \
ed25519/ecdsagen.c openssl/prf.c
am__objects_3 = chacha-poly1305/chacha.$(OBJEXT) \
openssl/digest.h openssl/prf.c nolegacy/crypto.c \
nolegacy/prf.c
am__objects_6 = chacha-poly1305/chacha.$(OBJEXT) \
chacha-poly1305/chacha-poly1305.$(OBJEXT) \
chacha-poly1305/poly1305.$(OBJEXT)
@OPENSSL_TRUE@am__objects_4 = openssl/crypto.$(OBJEXT) \
@OPENSSL_TRUE@ openssl/digest.$(OBJEXT) ed25519/ecdh.$(OBJEXT) \
@OPENSSL_TRUE@ ed25519/ecdsa.$(OBJEXT) \
@OPENSSL_TRUE@ ed25519/ecdsagen.$(OBJEXT) openssl/prf.$(OBJEXT)
@OPENSSL_TRUE@am__objects_7 = openssl/crypto.$(OBJEXT) \
@OPENSSL_TRUE@ openssl/digest.$(OBJEXT) openssl/prf.$(OBJEXT)
@GCRYPT_TRUE@@OPENSSL_FALSE@am__objects_8 = openssl/crypto.$(OBJEXT) \
@GCRYPT_TRUE@@OPENSSL_FALSE@ openssl/digest.$(OBJEXT) \
@GCRYPT_TRUE@@OPENSSL_FALSE@ openssl/prf.$(OBJEXT)
@GCRYPT_FALSE@@OPENSSL_FALSE@am__objects_9 = \
@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/crypto.$(OBJEXT) \
@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/prf.$(OBJEXT)
am_sptps_speed_OBJECTS = logger.$(OBJEXT) sptps.$(OBJEXT) \
sptps_speed.$(OBJEXT) utils.$(OBJEXT) $(am__objects_1) \
$(am__objects_3) $(am__objects_4)
sptps_speed.$(OBJEXT) utils.$(OBJEXT) ed25519/ecdh.$(OBJEXT) \
ed25519/ecdsa.$(OBJEXT) ed25519/ecdsagen.$(OBJEXT) \
$(am__objects_1) $(am__objects_6) $(am__objects_7) \
$(am__objects_8) $(am__objects_9)
sptps_speed_OBJECTS = $(am_sptps_speed_OBJECTS)
sptps_speed_DEPENDENCIES =
am__sptps_test_SOURCES_DIST = logger.c logger.h sptps.c sptps.h \
sptps_test.c utils.c utils.h ed25519/add_scalar.c \
ed25519/ed25519.h ed25519/fe.c ed25519/fe.h ed25519/fixedint.h \
ed25519/ge.c ed25519/ge.h ed25519/key_exchange.c \
ed25519/keypair.c ed25519/precomp_data.h ed25519/sc.c \
ed25519/sc.h ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \
sptps_test.c utils.c utils.h ed25519/ecdh.c ed25519/ecdsa.c \
ed25519/add_scalar.c ed25519/ed25519.h ed25519/fe.c \
ed25519/fe.h ed25519/fixedint.h ed25519/ge.c ed25519/ge.h \
ed25519/key_exchange.c ed25519/keypair.c \
ed25519/precomp_data.h ed25519/sc.c ed25519/sc.h \
ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \
ed25519/verify.c chacha-poly1305/chacha.c \
chacha-poly1305/chacha.h chacha-poly1305/chacha-poly1305.c \
chacha-poly1305/chacha-poly1305.h chacha-poly1305/poly1305.c \
chacha-poly1305/poly1305.h openssl/crypto.c openssl/digest.c \
openssl/digest.h ed25519/ecdh.c ed25519/ecdsa.c openssl/prf.c \
gcrypt/cipher.c gcrypt/crypto.c gcrypt/digest.c \
gcrypt/digest.h gcrypt/ecdh.c gcrypt/ecdsa.c gcrypt/prf.c
@OPENSSL_TRUE@am__objects_5 = openssl/crypto.$(OBJEXT) \
@OPENSSL_TRUE@ openssl/digest.$(OBJEXT) ed25519/ecdh.$(OBJEXT) \
@OPENSSL_TRUE@ ed25519/ecdsa.$(OBJEXT) openssl/prf.$(OBJEXT)
@GCRYPT_TRUE@am__objects_6 = gcrypt/cipher.$(OBJEXT) \
@GCRYPT_TRUE@ gcrypt/crypto.$(OBJEXT) gcrypt/digest.$(OBJEXT) \
@GCRYPT_TRUE@ gcrypt/ecdh.$(OBJEXT) gcrypt/ecdsa.$(OBJEXT) \
@GCRYPT_TRUE@ gcrypt/prf.$(OBJEXT)
chacha-poly1305/poly1305.h getopt.c getopt.h getopt1.c \
openssl/crypto.c openssl/digest.c openssl/digest.h \
openssl/prf.c gcrypt/cipher.c gcrypt/crypto.c gcrypt/digest.c \
gcrypt/digest.h gcrypt/prf.c nolegacy/crypto.c nolegacy/prf.c
@GCRYPT_TRUE@@OPENSSL_FALSE@am__objects_10 = gcrypt/cipher.$(OBJEXT) \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/crypto.$(OBJEXT) \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/digest.$(OBJEXT) \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/prf.$(OBJEXT)
am_sptps_test_OBJECTS = logger.$(OBJEXT) sptps.$(OBJEXT) \
sptps_test.$(OBJEXT) utils.$(OBJEXT) $(am__objects_1) \
$(am__objects_3) $(am__objects_5) $(am__objects_6)
sptps_test.$(OBJEXT) utils.$(OBJEXT) ed25519/ecdh.$(OBJEXT) \
ed25519/ecdsa.$(OBJEXT) $(am__objects_1) $(am__objects_6) \
$(am__objects_2) $(am__objects_7) $(am__objects_10) \
$(am__objects_9)
sptps_test_OBJECTS = $(am_sptps_test_OBJECTS)
sptps_test_LDADD = $(LDADD)
am__tinc_SOURCES_DIST = dropin.c dropin.h getopt.c getopt.h getopt1.c \
info.c info.h invitation.c invitation.h list.c list.h names.c \
names.h netutl.c netutl.h script.c script.h sptps.c sptps.h \
subnet_parse.c subnet.h tincctl.c tincctl.h top.c top.h \
utils.c utils.h version.c version.h ed25519/add_scalar.c \
am__tinc_SOURCES_DIST = dropin.c dropin.h fsck.c fsck.h ifconfig.c \
ifconfig.h info.c info.h invitation.c invitation.h list.c \
list.h names.c names.h netutl.c netutl.h script.c script.h \
sptps.c sptps.h subnet_parse.c subnet.h tincctl.c tincctl.h \
top.c top.h utils.c utils.h version.c version.h ed25519/ecdh.c \
ed25519/ecdsa.c ed25519/ecdsagen.c ed25519/add_scalar.c \
ed25519/ed25519.h ed25519/fe.c ed25519/fe.h ed25519/fixedint.h \
ed25519/ge.c ed25519/ge.h ed25519/key_exchange.c \
ed25519/keypair.c ed25519/precomp_data.h ed25519/sc.c \
@ -257,30 +305,31 @@ am__tinc_SOURCES_DIST = dropin.c dropin.h getopt.c getopt.h getopt1.c \
ed25519/verify.c chacha-poly1305/chacha.c \
chacha-poly1305/chacha.h chacha-poly1305/chacha-poly1305.c \
chacha-poly1305/chacha-poly1305.h chacha-poly1305/poly1305.c \
chacha-poly1305/poly1305.h openssl/cipher.c openssl/crypto.c \
openssl/digest.c openssl/digest.h ed25519/ecdh.c \
ed25519/ecdsa.c ed25519/ecdsagen.c openssl/prf.c openssl/rsa.c \
openssl/rsagen.c gcrypt/cipher.c gcrypt/crypto.c \
gcrypt/digest.c gcrypt/digest.h gcrypt/ecdh.c gcrypt/ecdsa.c \
gcrypt/ecdsagen.c gcrypt/prf.c gcrypt/rsa.c gcrypt/rsagen.c
@OPENSSL_TRUE@am__objects_7 = openssl/cipher.$(OBJEXT) \
chacha-poly1305/poly1305.h getopt.c getopt.h getopt1.c \
openssl/cipher.c openssl/crypto.c openssl/digest.c \
openssl/digest.h openssl/prf.c openssl/rsa.c openssl/rsagen.c \
gcrypt/cipher.c gcrypt/crypto.c gcrypt/digest.c \
gcrypt/digest.h gcrypt/prf.c gcrypt/rsa.c gcrypt/rsagen.c \
nolegacy/crypto.c nolegacy/prf.c
@OPENSSL_TRUE@am__objects_11 = openssl/cipher.$(OBJEXT) \
@OPENSSL_TRUE@ openssl/crypto.$(OBJEXT) \
@OPENSSL_TRUE@ openssl/digest.$(OBJEXT) ed25519/ecdh.$(OBJEXT) \
@OPENSSL_TRUE@ ed25519/ecdsa.$(OBJEXT) \
@OPENSSL_TRUE@ ed25519/ecdsagen.$(OBJEXT) openssl/prf.$(OBJEXT) \
@OPENSSL_TRUE@ openssl/digest.$(OBJEXT) openssl/prf.$(OBJEXT) \
@OPENSSL_TRUE@ openssl/rsa.$(OBJEXT) openssl/rsagen.$(OBJEXT)
@GCRYPT_TRUE@am__objects_8 = gcrypt/cipher.$(OBJEXT) \
@GCRYPT_TRUE@ gcrypt/crypto.$(OBJEXT) gcrypt/digest.$(OBJEXT) \
@GCRYPT_TRUE@ gcrypt/ecdh.$(OBJEXT) gcrypt/ecdsa.$(OBJEXT) \
@GCRYPT_TRUE@ gcrypt/ecdsagen.$(OBJEXT) gcrypt/prf.$(OBJEXT) \
@GCRYPT_TRUE@ gcrypt/rsa.$(OBJEXT) gcrypt/rsagen.$(OBJEXT)
am_tinc_OBJECTS = dropin.$(OBJEXT) getopt.$(OBJEXT) getopt1.$(OBJEXT) \
@GCRYPT_TRUE@@OPENSSL_FALSE@am__objects_12 = gcrypt/cipher.$(OBJEXT) \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/crypto.$(OBJEXT) \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/digest.$(OBJEXT) \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/prf.$(OBJEXT) \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/rsa.$(OBJEXT) \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/rsagen.$(OBJEXT)
am_tinc_OBJECTS = dropin.$(OBJEXT) fsck.$(OBJEXT) ifconfig.$(OBJEXT) \
info.$(OBJEXT) invitation.$(OBJEXT) list.$(OBJEXT) \
names.$(OBJEXT) netutl.$(OBJEXT) script.$(OBJEXT) \
sptps.$(OBJEXT) subnet_parse.$(OBJEXT) tincctl.$(OBJEXT) \
top.$(OBJEXT) utils.$(OBJEXT) version.$(OBJEXT) \
$(am__objects_1) $(am__objects_3) $(am__objects_7) \
$(am__objects_8)
ed25519/ecdh.$(OBJEXT) ed25519/ecdsa.$(OBJEXT) \
ed25519/ecdsagen.$(OBJEXT) $(am__objects_1) $(am__objects_6) \
$(am__objects_2) $(am__objects_11) $(am__objects_12) \
$(am__objects_9)
tinc_OBJECTS = $(am_tinc_OBJECTS)
am__DEPENDENCIES_1 =
tinc_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
@ -288,73 +337,74 @@ am__tincd_SOURCES_DIST = buffer.c buffer.h cipher.h conf.c conf.h \
connection.c connection.h control.c control.h control_common.h \
crypto.h device.h digest.h dropin.c dropin.h dummy_device.c \
ecdh.h ecdsa.h ecdsagen.h edge.c edge.h ethernet.h event.c \
event.h fake-gai-errnos.h fake-getaddrinfo.c \
fake-getaddrinfo.h fake-getnameinfo.c fake-getnameinfo.h \
getopt.c getopt.h getopt1.c graph.c graph.h hash.c hash.h \
have.h ipv4.h ipv6.h list.c list.h logger.c logger.h meta.c \
meta.h multicast_device.c names.c names.h net.c net.h \
net_packet.c net_setup.c net_socket.c netutl.c netutl.h node.c \
node.h prf.h process.c process.h protocol.c protocol.h \
protocol_auth.c protocol_edge.c protocol_key.c protocol_misc.c \
event.h graph.c graph.h hash.c hash.h have.h ipv4.h ipv6.h \
list.c list.h logger.c logger.h meta.c meta.h \
multicast_device.c names.c names.h net.c net.h net_packet.c \
net_setup.c net_socket.c netutl.c netutl.h node.c node.h prf.h \
process.c process.h protocol.c protocol.h protocol_auth.c \
protocol_edge.c protocol_key.c protocol_misc.c \
protocol_subnet.c raw_socket_device.c route.c route.h rsa.h \
rsagen.h script.c script.h splay_tree.c splay_tree.h sptps.c \
sptps.h subnet.c subnet.h subnet_parse.c system.h tincd.c \
utils.c utils.h xalloc.h version.c version.h \
ed25519/add_scalar.c ed25519/ed25519.h ed25519/fe.c \
ed25519/fe.h ed25519/fixedint.h ed25519/ge.c ed25519/ge.h \
ed25519/key_exchange.c ed25519/keypair.c \
utils.c utils.h xalloc.h version.c version.h ed25519/ecdh.c \
ed25519/ecdsa.c ed25519/add_scalar.c ed25519/ed25519.h \
ed25519/fe.c ed25519/fe.h ed25519/fixedint.h ed25519/ge.c \
ed25519/ge.h ed25519/key_exchange.c ed25519/keypair.c \
ed25519/precomp_data.h ed25519/sc.c ed25519/sc.h \
ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \
ed25519/verify.c chacha-poly1305/chacha.c \
chacha-poly1305/chacha.h chacha-poly1305/chacha-poly1305.c \
chacha-poly1305/chacha-poly1305.h chacha-poly1305/poly1305.c \
chacha-poly1305/poly1305.h linux/device.c bsd/device.c \
bsd/tunemu.c bsd/tunemu.h solaris/device.c mingw/device.c \
mingw/common.h cygwin/device.c uml_device.c vde_device.c \
openssl/cipher.c openssl/crypto.c openssl/digest.c \
openssl/digest.h ed25519/ecdh.c ed25519/ecdsa.c openssl/prf.c \
openssl/rsa.c gcrypt/cipher.c gcrypt/crypto.c gcrypt/digest.c \
gcrypt/digest.h gcrypt/ecdh.c gcrypt/ecdsa.c gcrypt/prf.c \
gcrypt/rsa.c
@LINUX_TRUE@am__objects_9 = linux/device.$(OBJEXT)
@BSD_TRUE@am__objects_10 = bsd/device.$(OBJEXT)
@BSD_TRUE@@TUNEMU_TRUE@am__objects_11 = bsd/tunemu.$(OBJEXT)
@SOLARIS_TRUE@am__objects_12 = solaris/device.$(OBJEXT)
@MINGW_TRUE@am__objects_13 = mingw/device.$(OBJEXT)
@CYGWIN_TRUE@am__objects_14 = cygwin/device.$(OBJEXT)
@UML_TRUE@am__objects_15 = uml_device.$(OBJEXT)
@VDE_TRUE@am__objects_16 = vde_device.$(OBJEXT)
@OPENSSL_TRUE@am__objects_17 = openssl/cipher.$(OBJEXT) \
chacha-poly1305/poly1305.h getopt.c getopt.h getopt1.c \
linux/device.c bsd/device.c bsd/tunemu.c bsd/tunemu.h \
solaris/device.c mingw/device.c mingw/common.h cygwin/device.c \
uml_device.c vde_device.c openssl/cipher.c openssl/crypto.c \
openssl/digest.c openssl/digest.h openssl/prf.c openssl/rsa.c \
gcrypt/cipher.c gcrypt/crypto.c gcrypt/digest.c \
gcrypt/digest.h gcrypt/prf.c gcrypt/rsa.c nolegacy/crypto.c \
nolegacy/prf.c upnp.h upnp.c
@LINUX_TRUE@am__objects_13 = linux/device.$(OBJEXT)
@BSD_TRUE@am__objects_14 = bsd/device.$(OBJEXT)
@BSD_TRUE@@TUNEMU_TRUE@am__objects_15 = bsd/tunemu.$(OBJEXT)
@SOLARIS_TRUE@am__objects_16 = solaris/device.$(OBJEXT)
@MINGW_TRUE@am__objects_17 = mingw/device.$(OBJEXT)
@CYGWIN_TRUE@am__objects_18 = cygwin/device.$(OBJEXT)
@UML_TRUE@am__objects_19 = uml_device.$(OBJEXT)
@VDE_TRUE@am__objects_20 = vde_device.$(OBJEXT)
@OPENSSL_TRUE@am__objects_21 = openssl/cipher.$(OBJEXT) \
@OPENSSL_TRUE@ openssl/crypto.$(OBJEXT) \
@OPENSSL_TRUE@ openssl/digest.$(OBJEXT) ed25519/ecdh.$(OBJEXT) \
@OPENSSL_TRUE@ ed25519/ecdsa.$(OBJEXT) openssl/prf.$(OBJEXT) \
@OPENSSL_TRUE@ openssl/digest.$(OBJEXT) openssl/prf.$(OBJEXT) \
@OPENSSL_TRUE@ openssl/rsa.$(OBJEXT)
@GCRYPT_TRUE@am__objects_18 = gcrypt/cipher.$(OBJEXT) \
@GCRYPT_TRUE@ gcrypt/crypto.$(OBJEXT) gcrypt/digest.$(OBJEXT) \
@GCRYPT_TRUE@ gcrypt/ecdh.$(OBJEXT) gcrypt/ecdsa.$(OBJEXT) \
@GCRYPT_TRUE@ gcrypt/prf.$(OBJEXT) gcrypt/rsa.$(OBJEXT)
@GCRYPT_TRUE@@OPENSSL_FALSE@am__objects_22 = gcrypt/cipher.$(OBJEXT) \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/crypto.$(OBJEXT) \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/digest.$(OBJEXT) \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/prf.$(OBJEXT) \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/rsa.$(OBJEXT)
@MINIUPNPC_TRUE@am__objects_23 = upnp.$(OBJEXT)
am_tincd_OBJECTS = buffer.$(OBJEXT) conf.$(OBJEXT) \
connection.$(OBJEXT) control.$(OBJEXT) dropin.$(OBJEXT) \
dummy_device.$(OBJEXT) edge.$(OBJEXT) event.$(OBJEXT) \
fake-getaddrinfo.$(OBJEXT) fake-getnameinfo.$(OBJEXT) \
getopt.$(OBJEXT) getopt1.$(OBJEXT) graph.$(OBJEXT) \
hash.$(OBJEXT) list.$(OBJEXT) logger.$(OBJEXT) meta.$(OBJEXT) \
multicast_device.$(OBJEXT) names.$(OBJEXT) net.$(OBJEXT) \
net_packet.$(OBJEXT) net_setup.$(OBJEXT) net_socket.$(OBJEXT) \
netutl.$(OBJEXT) node.$(OBJEXT) process.$(OBJEXT) \
protocol.$(OBJEXT) protocol_auth.$(OBJEXT) \
graph.$(OBJEXT) hash.$(OBJEXT) list.$(OBJEXT) logger.$(OBJEXT) \
meta.$(OBJEXT) multicast_device.$(OBJEXT) names.$(OBJEXT) \
net.$(OBJEXT) net_packet.$(OBJEXT) net_setup.$(OBJEXT) \
net_socket.$(OBJEXT) netutl.$(OBJEXT) node.$(OBJEXT) \
process.$(OBJEXT) protocol.$(OBJEXT) protocol_auth.$(OBJEXT) \
protocol_edge.$(OBJEXT) protocol_key.$(OBJEXT) \
protocol_misc.$(OBJEXT) protocol_subnet.$(OBJEXT) \
raw_socket_device.$(OBJEXT) route.$(OBJEXT) script.$(OBJEXT) \
splay_tree.$(OBJEXT) sptps.$(OBJEXT) subnet.$(OBJEXT) \
subnet_parse.$(OBJEXT) tincd.$(OBJEXT) utils.$(OBJEXT) \
version.$(OBJEXT) $(am__objects_1) $(am__objects_3) \
$(am__objects_9) $(am__objects_10) $(am__objects_11) \
$(am__objects_12) $(am__objects_13) $(am__objects_14) \
version.$(OBJEXT) ed25519/ecdh.$(OBJEXT) \
ed25519/ecdsa.$(OBJEXT) $(am__objects_1) $(am__objects_6) \
$(am__objects_2) $(am__objects_13) $(am__objects_14) \
$(am__objects_15) $(am__objects_16) $(am__objects_17) \
$(am__objects_18)
$(am__objects_18) $(am__objects_19) $(am__objects_20) \
$(am__objects_21) $(am__objects_22) $(am__objects_9) \
$(am__objects_23)
tincd_OBJECTS = $(am_tincd_OBJECTS)
tincd_LDADD = $(LDADD)
@MINIUPNPC_TRUE@tincd_DEPENDENCIES = $(am__DEPENDENCIES_1)
tincd_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(tincd_LDFLAGS) \
$(LDFLAGS) -o $@
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
@ -367,6 +417,7 @@ 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 =
DEFAULT_INCLUDES =
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
@ -411,6 +462,7 @@ am__define_uniq_tagged_files = \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@ -441,10 +493,11 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@ $(am__append_18)
LIBS = @LIBS@ -lm $(am__append_30)
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MINIUPNPC_LIBS = @MINIUPNPC_LIBS@
MKDIR_P = @MKDIR_P@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
@ -502,15 +555,17 @@ 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@
DEFAULT_INCLUDES =
CLEANFILES = version_git.h
ed25519_SOURCES = \
ed25519/add_scalar.c \
ed25519/ed25519.h \
@ -534,39 +589,47 @@ tincd_SOURCES = buffer.c buffer.h cipher.h conf.c conf.h connection.c \
connection.h control.c control.h control_common.h crypto.h \
device.h digest.h dropin.c dropin.h dummy_device.c ecdh.h \
ecdsa.h ecdsagen.h edge.c edge.h ethernet.h event.c event.h \
fake-gai-errnos.h fake-getaddrinfo.c fake-getaddrinfo.h \
fake-getnameinfo.c fake-getnameinfo.h getopt.c getopt.h \
getopt1.c graph.c graph.h hash.c hash.h have.h ipv4.h ipv6.h \
list.c list.h logger.c logger.h meta.c meta.h \
multicast_device.c names.c names.h net.c net.h net_packet.c \
net_setup.c net_socket.c netutl.c netutl.h node.c node.h prf.h \
process.c process.h protocol.c protocol.h protocol_auth.c \
graph.c graph.h hash.c hash.h have.h ipv4.h ipv6.h list.c \
list.h logger.c logger.h meta.c meta.h multicast_device.c \
names.c names.h net.c net.h net_packet.c net_setup.c \
net_socket.c netutl.c netutl.h node.c node.h prf.h process.c \
process.h protocol.c protocol.h protocol_auth.c \
protocol_edge.c protocol_key.c protocol_misc.c \
protocol_subnet.c raw_socket_device.c route.c route.h rsa.h \
rsagen.h script.c script.h splay_tree.c splay_tree.h sptps.c \
sptps.h subnet.c subnet.h subnet_parse.c system.h tincd.c \
utils.c utils.h xalloc.h version.c version.h \
$(ed25519_SOURCES) $(chacha_poly1305_SOURCES) $(am__append_2) \
$(am__append_3) $(am__append_4) $(am__append_5) \
$(am__append_6) $(am__append_7) $(am__append_8) \
$(am__append_9) $(am__append_10) $(am__append_15)
tinc_SOURCES = dropin.c dropin.h getopt.c getopt.h getopt1.c info.c \
info.h invitation.c invitation.h list.c list.h names.c names.h \
netutl.c netutl.h script.c script.h sptps.c sptps.h \
utils.c utils.h xalloc.h version.c version.h ed25519/ecdh.c \
ed25519/ecdsa.c $(ed25519_SOURCES) $(chacha_poly1305_SOURCES) \
$(am__append_2) $(am__append_6) $(am__append_7) \
$(am__append_8) $(am__append_9) $(am__append_10) \
$(am__append_11) $(am__append_12) $(am__append_13) \
$(am__append_14) $(am__append_19) $(am__append_24) \
$(am__append_29)
tinc_SOURCES = dropin.c dropin.h fsck.c fsck.h ifconfig.c ifconfig.h \
info.c info.h invitation.c invitation.h list.c list.h names.c \
names.h netutl.c netutl.h script.c script.h sptps.c sptps.h \
subnet_parse.c subnet.h tincctl.c tincctl.h top.c top.h \
utils.c utils.h version.c version.h $(ed25519_SOURCES) \
$(chacha_poly1305_SOURCES) $(am__append_11) $(am__append_16)
utils.c utils.h version.c version.h ed25519/ecdh.c \
ed25519/ecdsa.c ed25519/ecdsagen.c $(ed25519_SOURCES) \
$(chacha_poly1305_SOURCES) $(am__append_3) $(am__append_15) \
$(am__append_20) $(am__append_25)
sptps_test_SOURCES = logger.c logger.h sptps.c sptps.h sptps_test.c \
utils.c utils.h $(ed25519_SOURCES) $(chacha_poly1305_SOURCES) \
$(am__append_12) $(am__append_17)
utils.c utils.h ed25519/ecdh.c ed25519/ecdsa.c \
$(ed25519_SOURCES) $(chacha_poly1305_SOURCES) $(am__append_4) \
$(am__append_16) $(am__append_21) $(am__append_26)
sptps_keypair_SOURCES = sptps_keypair.c utils.c utils.h \
$(ed25519_SOURCES) $(am__append_13)
ed25519/ecdsagen.c $(ed25519_SOURCES) $(am__append_5) \
$(am__append_17) $(am__append_22) $(am__append_27)
sptps_speed_SOURCES = logger.c logger.h sptps.c sptps.h sptps_speed.c \
utils.c utils.h $(ed25519_SOURCES) $(chacha_poly1305_SOURCES) \
$(am__append_14)
utils.c utils.h ed25519/ecdh.c ed25519/ecdsa.c \
ed25519/ecdsagen.c $(ed25519_SOURCES) \
$(chacha_poly1305_SOURCES) $(am__append_18) $(am__append_23) \
$(am__append_28)
@MINIUPNPC_TRUE@tincd_LDADD = $(MINIUPNPC_LIBS)
@MINIUPNPC_TRUE@tincd_LDFLAGS = -pthread
tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS)
sptps_speed_LDADD = -lrt
AM_CFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DSBINDIR=\"$(sbindir)\"
AM_CFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DSBINDIR=\"$(sbindir)\" -iquote.
all: all-am
.SUFFIXES:
@ -583,7 +646,6 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu src/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@ -665,6 +727,8 @@ ed25519/$(am__dirstamp):
ed25519/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) ed25519/$(DEPDIR)
@: > ed25519/$(DEPDIR)/$(am__dirstamp)
ed25519/ecdsagen.$(OBJEXT): ed25519/$(am__dirstamp) \
ed25519/$(DEPDIR)/$(am__dirstamp)
ed25519/add_scalar.$(OBJEXT): ed25519/$(am__dirstamp) \
ed25519/$(DEPDIR)/$(am__dirstamp)
ed25519/fe.$(OBJEXT): ed25519/$(am__dirstamp) \
@ -691,12 +755,22 @@ openssl/$(DEPDIR)/$(am__dirstamp):
@: > openssl/$(DEPDIR)/$(am__dirstamp)
openssl/crypto.$(OBJEXT): openssl/$(am__dirstamp) \
openssl/$(DEPDIR)/$(am__dirstamp)
ed25519/ecdsagen.$(OBJEXT): ed25519/$(am__dirstamp) \
ed25519/$(DEPDIR)/$(am__dirstamp)
nolegacy/$(am__dirstamp):
@$(MKDIR_P) nolegacy
@: > nolegacy/$(am__dirstamp)
nolegacy/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) nolegacy/$(DEPDIR)
@: > nolegacy/$(DEPDIR)/$(am__dirstamp)
nolegacy/crypto.$(OBJEXT): nolegacy/$(am__dirstamp) \
nolegacy/$(DEPDIR)/$(am__dirstamp)
sptps_keypair$(EXEEXT): $(sptps_keypair_OBJECTS) $(sptps_keypair_DEPENDENCIES) $(EXTRA_sptps_keypair_DEPENDENCIES)
@rm -f sptps_keypair$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(sptps_keypair_OBJECTS) $(sptps_keypair_LDADD) $(LIBS)
ed25519/ecdh.$(OBJEXT): ed25519/$(am__dirstamp) \
ed25519/$(DEPDIR)/$(am__dirstamp)
ed25519/ecdsa.$(OBJEXT): ed25519/$(am__dirstamp) \
ed25519/$(DEPDIR)/$(am__dirstamp)
chacha-poly1305/$(am__dirstamp):
@$(MKDIR_P) chacha-poly1305
@: > chacha-poly1305/$(am__dirstamp)
@ -712,12 +786,10 @@ chacha-poly1305/poly1305.$(OBJEXT): chacha-poly1305/$(am__dirstamp) \
chacha-poly1305/$(DEPDIR)/$(am__dirstamp)
openssl/digest.$(OBJEXT): openssl/$(am__dirstamp) \
openssl/$(DEPDIR)/$(am__dirstamp)
ed25519/ecdh.$(OBJEXT): ed25519/$(am__dirstamp) \
ed25519/$(DEPDIR)/$(am__dirstamp)
ed25519/ecdsa.$(OBJEXT): ed25519/$(am__dirstamp) \
ed25519/$(DEPDIR)/$(am__dirstamp)
openssl/prf.$(OBJEXT): openssl/$(am__dirstamp) \
openssl/$(DEPDIR)/$(am__dirstamp)
nolegacy/prf.$(OBJEXT): nolegacy/$(am__dirstamp) \
nolegacy/$(DEPDIR)/$(am__dirstamp)
sptps_speed$(EXEEXT): $(sptps_speed_OBJECTS) $(sptps_speed_DEPENDENCIES) $(EXTRA_sptps_speed_DEPENDENCIES)
@rm -f sptps_speed$(EXEEXT)
@ -734,10 +806,6 @@ gcrypt/crypto.$(OBJEXT): gcrypt/$(am__dirstamp) \
gcrypt/$(DEPDIR)/$(am__dirstamp)
gcrypt/digest.$(OBJEXT): gcrypt/$(am__dirstamp) \
gcrypt/$(DEPDIR)/$(am__dirstamp)
gcrypt/ecdh.$(OBJEXT): gcrypt/$(am__dirstamp) \
gcrypt/$(DEPDIR)/$(am__dirstamp)
gcrypt/ecdsa.$(OBJEXT): gcrypt/$(am__dirstamp) \
gcrypt/$(DEPDIR)/$(am__dirstamp)
gcrypt/prf.$(OBJEXT): gcrypt/$(am__dirstamp) \
gcrypt/$(DEPDIR)/$(am__dirstamp)
@ -750,8 +818,6 @@ openssl/rsa.$(OBJEXT): openssl/$(am__dirstamp) \
openssl/$(DEPDIR)/$(am__dirstamp)
openssl/rsagen.$(OBJEXT): openssl/$(am__dirstamp) \
openssl/$(DEPDIR)/$(am__dirstamp)
gcrypt/ecdsagen.$(OBJEXT): gcrypt/$(am__dirstamp) \
gcrypt/$(DEPDIR)/$(am__dirstamp)
gcrypt/rsa.$(OBJEXT): gcrypt/$(am__dirstamp) \
gcrypt/$(DEPDIR)/$(am__dirstamp)
gcrypt/rsagen.$(OBJEXT): gcrypt/$(am__dirstamp) \
@ -805,7 +871,7 @@ cygwin/device.$(OBJEXT): cygwin/$(am__dirstamp) \
tincd$(EXEEXT): $(tincd_OBJECTS) $(tincd_DEPENDENCIES) $(EXTRA_tincd_DEPENDENCIES)
@rm -f tincd$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(tincd_OBJECTS) $(tincd_LDADD) $(LIBS)
$(AM_V_CCLD)$(tincd_LINK) $(tincd_OBJECTS) $(tincd_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@ -816,6 +882,7 @@ mostlyclean-compile:
-rm -f gcrypt/*.$(OBJEXT)
-rm -f linux/*.$(OBJEXT)
-rm -f mingw/*.$(OBJEXT)
-rm -f nolegacy/*.$(OBJEXT)
-rm -f openssl/*.$(OBJEXT)
-rm -f solaris/*.$(OBJEXT)
@ -830,12 +897,12 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy_device.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edge.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fake-getaddrinfo.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fake-getnameinfo.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsck.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/graph.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ifconfig.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/info.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/invitation.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Po@am__quote@
@ -870,6 +937,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tincd.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/top.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uml_device.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upnp.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vde_device.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Po@am__quote@
@ -894,14 +962,13 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/cipher.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/crypto.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/digest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/ecdh.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/ecdsa.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/ecdsagen.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/prf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/rsa.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/rsagen.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@linux/$(DEPDIR)/device.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@mingw/$(DEPDIR)/device.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@nolegacy/$(DEPDIR)/crypto.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@nolegacy/$(DEPDIR)/prf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/cipher.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/crypto.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/digest.Po@am__quote@
@ -1037,6 +1104,7 @@ install-strip:
mostlyclean-generic:
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
@ -1055,6 +1123,8 @@ distclean-generic:
-rm -f linux/$(am__dirstamp)
-rm -f mingw/$(DEPDIR)/$(am__dirstamp)
-rm -f mingw/$(am__dirstamp)
-rm -f nolegacy/$(DEPDIR)/$(am__dirstamp)
-rm -f nolegacy/$(am__dirstamp)
-rm -f openssl/$(DEPDIR)/$(am__dirstamp)
-rm -f openssl/$(am__dirstamp)
-rm -f solaris/$(DEPDIR)/$(am__dirstamp)
@ -1068,7 +1138,7 @@ clean: clean-am
clean-am: clean-generic clean-sbinPROGRAMS mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR) bsd/$(DEPDIR) chacha-poly1305/$(DEPDIR) cygwin/$(DEPDIR) ed25519/$(DEPDIR) gcrypt/$(DEPDIR) linux/$(DEPDIR) mingw/$(DEPDIR) openssl/$(DEPDIR) solaris/$(DEPDIR)
-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 Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
@ -1114,7 +1184,7 @@ install-ps-am:
installcheck-am: installcheck-sbinPROGRAMS
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR) bsd/$(DEPDIR) chacha-poly1305/$(DEPDIR) cygwin/$(DEPDIR) ed25519/$(DEPDIR) gcrypt/$(DEPDIR) linux/$(DEPDIR) mingw/$(DEPDIR) openssl/$(DEPDIR) solaris/$(DEPDIR)
-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 Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
@ -1148,9 +1218,18 @@ uninstall-am: uninstall-sbinPROGRAMS
mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \
uninstall-am uninstall-sbinPROGRAMS
.PRECIOUS: Makefile
.PHONY: version.c
version.c:
.PHONY: version-stamp
version-stamp:
version_git.h: version-stamp
$(AM_V_GEN)echo >$@
@-(cd $(srcdir) && git describe 2>/dev/null >/dev/null) && echo '#define GIT_DESCRIPTION "'`(cd $(srcdir) && git describe) | sed 's/release-//'`'"' >$@ ||:
${srcdir}/version.c: version_git.h
@BSD_TRUE@version.c: ${srcdir}/version.c
# 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.

View file

@ -1,7 +1,7 @@
/*
device.c -- Interaction BSD tun/tap device
Copyright (C) 2001-2005 Ivo Timmermans,
2001-2014 Guus Sliepen <guus@tinc-vpn.org>
2001-2016 Guus Sliepen <guus@tinc-vpn.org>
2009 Grzegorz Dymarek <gregd72002@googlemail.com>
This program is free software; you can redistribute it and/or modify
@ -34,13 +34,15 @@
#include "bsd/tunemu.h"
#endif
#define DEFAULT_TUN_DEVICE "/dev/tun0"
#if defined(HAVE_DARWIN) || defined(HAVE_FREEBSD) || defined(HAVE_NETBSD)
#define DEFAULT_TAP_DEVICE "/dev/tap0"
#else
#define DEFAULT_TAP_DEVICE "/dev/tun0"
#ifdef HAVE_NET_IF_UTUN_H
#include <sys/sys_domain.h>
#include <sys/kern_control.h>
#include <net/if_utun.h>
#endif
#define DEFAULT_TUN_DEVICE "/dev/tun0"
#define DEFAULT_TAP_DEVICE "/dev/tap0"
typedef enum device_type {
DEVICE_TYPE_TUN,
DEVICE_TYPE_TUNIFHEAD,
@ -48,6 +50,7 @@ typedef enum device_type {
#ifdef ENABLE_TUNEMU
DEVICE_TYPE_TUNEMU,
#endif
DEVICE_TYPE_UTUN,
} device_type_t;
int device_fd = -1;
@ -62,9 +65,64 @@ static device_type_t device_type = DEVICE_TYPE_TUNIFHEAD;
static device_type_t device_type = DEVICE_TYPE_TUN;
#endif
#ifdef HAVE_NET_IF_UTUN_H
static bool setup_utun(void) {
device_fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
if(device_fd == -1) {
logger(DEBUG_ALWAYS, LOG_ERR, "Could not open PF_SYSTEM socket: %s\n", strerror(errno));
return false;
}
struct ctl_info info = {};
strlcpy(info.ctl_name, UTUN_CONTROL_NAME, sizeof info.ctl_name);
if(ioctl(device_fd, CTLIOCGINFO, &info) == -1) {
logger(DEBUG_ALWAYS, LOG_ERR, "ioctl(CTLIOCGINFO) failed: %s", strerror(errno));
return false;
}
int unit = -1;
char *p = strstr(device, "utun"), *e = NULL;
if(p) {
unit = strtol(p + 4, &e, 10);
if(!e)
unit = -1;
}
struct sockaddr_ctl sc = {
.sc_id = info.ctl_id,
.sc_len = sizeof sc,
.sc_family = AF_SYSTEM,
.ss_sysaddr = AF_SYS_CONTROL,
.sc_unit = unit + 1,
};
if(connect(device_fd, (struct sockaddr *)&sc, sizeof(sc)) == -1) {
logger(DEBUG_ALWAYS, LOG_ERR, "Could not connect utun socket: %s\n", strerror(errno));
return false;
}
char name[64] = "";
socklen_t len = sizeof name;
if(getsockopt(device_fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, name, &len)) {
iface = xstrdup(device);
} else {
iface = xstrdup(name);
}
device_info = "OS X utun device";
logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info);
return true;
}
#endif
static bool setup_device(void) {
get_config_string(lookup_config(config_tree, "Device"), &device);
// Find out if it's supposed to be a tun or a tap device
char *type;
if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) {
if(!strcasecmp(type, "tun"))
@ -72,6 +130,10 @@ static bool setup_device(void) {
#ifdef ENABLE_TUNEMU
else if(!strcasecmp(type, "tunemu"))
device_type = DEVICE_TYPE_TUNEMU;
#endif
#ifdef HAVE_NET_IF_UTUN_H
else if(!strcasecmp(type, "utun"))
device_type = DEVICE_TYPE_UTUN;
#endif
else if(!strcasecmp(type, "tunnohead"))
device_type = DEVICE_TYPE_TUN;
@ -84,10 +146,22 @@ static bool setup_device(void) {
return false;
}
} else {
#ifdef HAVE_NET_IF_UTUN_H
if(device && (strncmp(device, "utun", 4) == 0 || strncmp(device, "/dev/utun", 9) == 0))
device_type = DEVICE_TYPE_UTUN;
else
#endif
if((device && strstr(device, "tap")) || routing_mode != RMODE_ROUTER)
device_type = DEVICE_TYPE_TAP;
}
if(routing_mode == RMODE_SWITCH && device_type != DEVICE_TYPE_TAP) {
logger(DEBUG_ALWAYS, LOG_ERR, "Only tap devices support switch mode!");
return false;
}
// Find out which device file to open
if(!device) {
if(device_type == DEVICE_TYPE_TAP)
device = xstrdup(DEFAULT_TAP_DEVICE);
@ -95,17 +169,7 @@ static bool setup_device(void) {
device = xstrdup(DEFAULT_TUN_DEVICE);
}
if(!get_config_string(lookup_config(config_tree, "Interface"), &iface))
iface = NULL;
#ifndef TAPGIFNAME
if (iface) {
logger(DEBUG_ALWAYS, LOG_WARNING, "Ignoring specified interface name '%s' as device rename is not supported on this platform", iface);
free(iface);
iface = NULL;
}
#endif
if (!iface)
iface = xstrdup(strrchr(device, '/') ? strrchr(device, '/') + 1 : device);
// Open the device
switch(device_type) {
#ifdef ENABLE_TUNEMU
@ -114,6 +178,10 @@ static bool setup_device(void) {
device_fd = tunemu_open(dynamic_name);
}
break;
#endif
#ifdef HAVE_NET_IF_UTUN_H
case DEVICE_TYPE_UTUN:
return setup_utun();
#endif
default:
device_fd = open(device, O_RDWR | O_NONBLOCK);
@ -128,6 +196,27 @@ static bool setup_device(void) {
fcntl(device_fd, F_SETFD, FD_CLOEXEC);
#endif
// Guess what the corresponding interface is called
char *realname;
#if defined(HAVE_FDEVNAME)
realname = fdevname(device_fd) ? : device;
#elif defined(HAVE_DEVNAME)
struct stat buf;
if(!fstat(device_fd, &buf))
realname = devname(buf.st_rdev, S_IFCHR) ? : device;
#else
realname = device;
#endif
if(!get_config_string(lookup_config(config_tree, "Interface"), &iface))
iface = xstrdup(strrchr(realname, '/') ? strrchr(realname, '/') + 1 : realname);
else if(strcmp(iface, strrchr(realname, '/') ? strrchr(realname, '/') + 1 : realname))
logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: Interface does not match Device. $INTERFACE might be set incorrectly.");
// Configure the device as best as we can
switch(device_type) {
default:
device_type = DEVICE_TYPE_TUN;
@ -192,6 +281,11 @@ static bool setup_device(void) {
#endif
}
#ifdef SIOCGIFADDR
if(overwrite_mac)
ioctl(device_fd, SIOCGIFADDR, mymac.x);
#endif
logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info);
return true;
@ -253,31 +347,29 @@ static bool read_packet(vpn_packet_t *packet) {
packet->len = inlen + 14;
break;
case DEVICE_TYPE_UTUN:
case DEVICE_TYPE_TUNIFHEAD: {
u_int32_t type;
struct iovec vector[2] = {{&type, sizeof type}, {DATA(packet) + 14, MTU - 14}};
if((inlen = readv(device_fd, vector, 2)) <= 0) {
if((inlen = read(device_fd, packet->data + 10, MTU - 10)) <= 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info,
device, strerror(errno));
return false;
}
switch (ntohl(type)) {
case AF_INET:
switch (packet->data[14] >> 4) {
case 4:
DATA(packet)[12] = 0x08;
DATA(packet)[13] = 0x00;
break;
case AF_INET6:
case 6:
DATA(packet)[12] = 0x86;
DATA(packet)[13] = 0xDD;
break;
default:
logger(DEBUG_TRAFFIC, LOG_ERR,
"Unknown address family %x while reading packet from %s %s",
ntohl(type), device_info, device);
"Unknown IP version %d while reading packet from %s %s",
packet->data[14] >> 4, device_info, device);
return false;
}
@ -319,12 +411,10 @@ static bool write_packet(vpn_packet_t *packet) {
}
break;
case DEVICE_TYPE_UTUN:
case DEVICE_TYPE_TUNIFHEAD: {
u_int32_t type;
struct iovec vector[2] = {{&type, sizeof type}, {DATA(packet) + 14, packet->len - 14}};
int af;
af = (DATA(packet)[12] << 8) + DATA(packet)[13];
int af = (DATA(packet)[12] << 8) + DATA(packet)[13];
uint32_t type;
switch (af) {
case 0x0800:
@ -340,7 +430,9 @@ static bool write_packet(vpn_packet_t *packet) {
return false;
}
if(writev(device_fd, vector, 2) < 0) {
memcpy(packet->data + 10, &type, sizeof type);
if(write(device_fd, packet->data + 10, packet->len - 10) < 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device,
strerror(errno));
return false;

View file

@ -24,6 +24,8 @@
#define CIPHER_MAX_IV_SIZE 16
#define CIPHER_MAX_KEY_SIZE 32
#ifndef DISABLE_LEGACY
typedef struct cipher cipher_t;
extern cipher_t *cipher_open_by_name(const char *) __attribute__ ((__malloc__));
@ -31,6 +33,7 @@ extern cipher_t *cipher_open_by_nid(int) __attribute__ ((__malloc__));
extern cipher_t *cipher_open_blowfish_ofb(void) __attribute__ ((__malloc__));
extern void cipher_close(cipher_t *);
extern size_t cipher_keylength(const cipher_t *);
extern size_t cipher_blocksize(const cipher_t *);
extern void cipher_get_key(const cipher_t *, void *);
extern bool cipher_set_key(cipher_t *, void *, bool) __attribute__ ((__warn_unused_result__));
extern bool cipher_set_key_from_rsa(cipher_t *, void *, size_t, bool) __attribute__ ((__warn_unused_result__));
@ -40,3 +43,5 @@ extern int cipher_get_nid(const cipher_t *);
extern bool cipher_active(const cipher_t *);
#endif
#endif

View file

@ -4,7 +4,7 @@
1998-2005 Ivo Timmermans
2000 Cris van Pelt
2010-2011 Julien Muchembled <jm@jmuchemb.eu>
2000-2013 Guus Sliepen <guus@tinc-vpn.org>
2000-2015 Guus Sliepen <guus@tinc-vpn.org>
2013 Florent Clairambault <florent@clairambault.fr>
This program is free software; you can redistribute it and/or modify
@ -298,7 +298,7 @@ bool read_config_file(splay_tree_t *config_tree, const char *fname) {
fp = fopen(fname, "r");
if(!fp) {
logger(DEBUG_ALWAYS, LOG_ERR, "Cannot open config file %s: %s", fname, strerror(errno));
logger(DEBUG_ALWAYS, LOG_DEBUG, "Cannot open config file %s: %s", fname, strerror(errno));
return false;
}
@ -368,19 +368,19 @@ void read_config_options(splay_tree_t *config_tree, const char *prefix) {
}
bool read_server_config(void) {
char *fname;
char fname[PATH_MAX];
bool x;
read_config_options(config_tree, NULL);
xasprintf(&fname, "%s" SLASH "tinc.conf", confbase);
snprintf(fname, sizeof fname, "%s" SLASH "tinc.conf", confbase);
errno = 0;
x = read_config_file(config_tree, fname);
// We will try to read the conf files in the "conf.d" dir
if (x) {
char * dname;
xasprintf(&dname, "%s" SLASH "conf.d", confbase);
char dname[PATH_MAX];
snprintf(dname, sizeof dname, "%s" SLASH "conf.d", confbase);
DIR *dir = opendir (dname);
// If we can find this dir
if (dir) {
@ -390,51 +390,44 @@ bool read_server_config(void) {
size_t l = strlen(ep->d_name);
// And we try to read the ones that end with ".conf"
if (l > 5 && !strcmp(".conf", & ep->d_name[ l - 5 ])) {
free(fname);
xasprintf(&fname, "%s" SLASH "%s", dname, ep->d_name);
snprintf(fname, sizeof fname, "%s" SLASH "%s", dname, ep->d_name);
x = read_config_file(config_tree, fname);
}
}
closedir (dir);
}
free(dname);
}
if(!x && errno)
logger(DEBUG_ALWAYS, LOG_ERR, "Failed to read `%s': %s", fname, strerror(errno));
free(fname);
return x;
}
bool read_host_config(splay_tree_t *config_tree, const char *name) {
char *fname;
char fname[PATH_MAX];
bool x;
read_config_options(config_tree, name);
xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, name);
snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, name);
x = read_config_file(config_tree, fname);
free(fname);
return x;
}
bool append_config_file(const char *name, const char *key, const char *value) {
char *fname;
xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, name);
char fname[PATH_MAX];
snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, name);
FILE *fp = fopen(fname, "a");
if(!fp) {
logger(DEBUG_ALWAYS, LOG_ERR, "Cannot open config file %s: %s", fname, strerror(errno));
} else {
fprintf(fp, "\n# The following line was automatically added by tinc\n%s = %s\n", key, value);
fclose(fp);
logger(DEBUG_ALWAYS, LOG_DEBUG, "Cannot open config file %s: %s", fname, strerror(errno));
return false;
}
free(fname);
return fp != NULL;
fprintf(fp, "\n# The following line was automatically added by tinc\n%s = %s\n", key, value);
fclose(fp);
return true;
}

View file

@ -21,8 +21,9 @@
#ifndef __TINC_CONF_H__
#define __TINC_CONF_H__
#include "splay_tree.h"
#include "list.h"
#include "splay_tree.h"
#include "subnet.h"
typedef struct config_t {
char *variable;
@ -31,7 +32,6 @@ typedef struct config_t {
int line;
} config_t;
#include "subnet.h"
extern splay_tree_t *config_tree;

View file

@ -55,14 +55,16 @@ void free_connection(connection_t *c) {
if(!c)
return;
#ifndef DISABLE_LEGACY
cipher_close(c->incipher);
digest_close(c->indigest);
cipher_close(c->outcipher);
digest_close(c->outdigest);
rsa_free(c->rsa);
#endif
sptps_stop(&c->sptps);
ecdsa_free(c->ecdsa);
rsa_free(c->rsa);
free(c->hischallenge);

View file

@ -59,9 +59,9 @@ typedef struct connection_status_t {
typedef struct connection_t {
char *name; /* name he claims to have */
char *hostname; /* the hostname of its real ip */
union sockaddr_t address; /* his real (internet) ip */
char *hostname; /* the hostname of its real ip */
int protocol_major; /* used protocol */
int protocol_minor; /* used protocol */
@ -75,12 +75,15 @@ typedef struct connection_t {
struct node_t *node; /* node associated with the other end */
struct edge_t *edge; /* edge associated with this connection */
#ifndef DISABLE_LEGACY
rsa_t *rsa; /* his public RSA key */
ecdsa_t *ecdsa; /* his public ECDSA key */
cipher_t *incipher; /* Cipher he will use to send data to us */
cipher_t *outcipher; /* Cipher we will use to send data to him */
digest_t *indigest;
digest_t *outdigest;
#endif
ecdsa_t *ecdsa; /* his public ECDSA key */
sptps_t sptps;
int inmaclength;
@ -94,6 +97,7 @@ typedef struct connection_t {
struct buffer_t outbuf;
io_t io; /* input/output event on this metadata connection */
int tcplen; /* length of incoming TCPpacket */
int sptpslen; /* length of incoming SPTPS packet */
int allow_request; /* defined if there's only one request possible */
time_t last_ping_time; /* last time we saw some activity from the other end or pinged them */

View file

@ -19,6 +19,7 @@
*/
#include "../system.h"
#include "../net.h"
#include <w32api/windows.h>
#include <w32api/winioctl.h>
@ -27,7 +28,6 @@
#include "../device.h"
#include "../logger.h"
#include "../names.h"
#include "../net.h"
#include "../route.h"
#include "../utils.h"
#include "../xalloc.h"
@ -59,6 +59,9 @@ static bool setup_device(void) {
get_config_string(lookup_config(config_tree, "Device"), &device);
get_config_string(lookup_config(config_tree, "Interface"), &iface);
if(device && iface)
logger(LOG_WARNING, "Warning: both Device and Interface specified, results may not be as expected");
/* Open registry and look for network adapters */
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, NETWORK_CONNECTIONS_KEY, 0, KEY_READ, &key)) {

View file

@ -22,6 +22,8 @@
#define DIGEST_MAX_SIZE 64
#ifndef DISABLE_LEGACY
typedef struct digest digest_t;
extern digest_t *digest_open_by_name(const char *name, int maclength) __attribute__ ((__malloc__));
@ -37,3 +39,5 @@ extern size_t digest_length(const digest_t *);
extern bool digest_active(const digest_t *);
#endif
#endif

View file

@ -1,7 +1,7 @@
/*
dropin.c -- a set of drop-in replacements for libc functions
Copyright (C) 2000-2005 Ivo Timmermans,
2000-2013 Guus Sliepen <guus@tinc-vpn.org>
2000-2016 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -86,40 +86,6 @@ int daemon(int nochdir, int noclose) {
}
#endif
#ifndef HAVE_GET_CURRENT_DIR_NAME
/*
Replacement for the GNU get_current_dir_name function:
get_current_dir_name will malloc(3) an array big enough to hold the
current directory name. If the environment variable PWD is set, and
its value is correct, then that value will be returned.
*/
char *get_current_dir_name(void) {
size_t size;
char *buf;
char *r;
/* Start with 100 bytes. If this turns out to be insufficient to
contain the working directory, double the size. */
size = 100;
buf = xmalloc(size);
errno = 0; /* Success */
r = getcwd(buf, size);
/* getcwd returns NULL and sets errno to ERANGE if the bufferspace
is insufficient to contain the entire working directory. */
while(r == NULL && errno == ERANGE) {
free(buf);
size <<= 1; /* double the size */
buf = xmalloc(size);
r = getcwd(buf, size);
}
return buf;
}
#endif
#ifndef HAVE_ASPRINTF
int asprintf(char **buf, const char *fmt, ...) {
int result;
@ -174,10 +140,9 @@ int gettimeofday(struct timeval *tv, void *tz) {
}
#endif
#ifndef HAVE_USLEEP
int usleep(long long usec) {
struct timeval tv = {usec / 1000000, (usec / 1000) % 1000};
select(0, NULL, NULL, NULL, &tv);
return 0;
#ifndef HAVE_NANOSLEEP
int nanosleep(const struct timespec *req, struct timespec *rem) {
struct timeval tv = {req->tv_sec, req->tv_nsec / 1000};
return select(0, NULL, NULL, NULL, &tv);
}
#endif

View file

@ -1,7 +1,7 @@
/*
dropin.h -- header file for dropin.c
Copyright (C) 2000-2005 Ivo Timmermans,
2000-2013 Guus Sliepen <guus@tinc-vpn.org>
2000-2016 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -21,17 +21,10 @@
#ifndef __DROPIN_H__
#define __DROPIN_H__
#include "fake-getaddrinfo.h"
#include "fake-getnameinfo.h"
#ifndef HAVE_DAEMON
extern int daemon(int, int);
#endif
#ifndef HAVE_GET_CURRENT_DIR_NAME
extern char *get_current_dir_name(void);
#endif
#ifndef HAVE_ASPRINTF
extern int asprintf(char **, const char *, ...);
extern int vasprintf(char **, const char *, va_list ap);
@ -41,8 +34,8 @@ extern int vasprintf(char **, const char *, va_list ap);
extern int gettimeofday(struct timeval *, void *);
#endif
#ifndef HAVE_USLEEP
extern int usleep(long long usec);
#ifndef HAVE_NANOSLEEP
extern int nanosleep(const struct timespec *req, struct timespec *rem);
#endif
#ifndef timeradd
@ -70,4 +63,8 @@ extern int usleep(long long usec);
#endif
#endif
#ifndef EAI_SYSTEM
#define EAI_SYSTEM 0
#endif
#endif /* __DROPIN_H__ */

View file

@ -84,11 +84,13 @@ static bool read_pem(FILE *fp, const char *type, void *buf, size_t size) {
size_t len = b64decode(line, line, linelen);
if(!len) {
logger(DEBUG_ALWAYS, LOG_ERR, "Invalid base64 data in PEM file\n");
errno = EINVAL;
return false;
}
if(len > size) {
logger(DEBUG_ALWAYS, LOG_ERR, "Too much base64 data in PEM file\n");
errno = EINVAL;
return false;
}
@ -98,7 +100,12 @@ static bool read_pem(FILE *fp, const char *type, void *buf, size_t size) {
}
if(size) {
if(data) {
errno = EINVAL;
logger(DEBUG_ALWAYS, LOG_ERR, "Too little base64 data in PEM file\n");
} else {
errno = ENOENT;
}
return false;
}

View file

@ -8,9 +8,9 @@
static uint64_t load_3(const unsigned char *in) {
uint64_t result;
result = (uint64_t) in[0];
result |= ((uint64_t) in[1]) << 8;
result |= ((uint64_t) in[2]) << 16;
result = in[0];
result |= shlu64(in[1], 8);
result |= shlu64(in[2], 16);
return result;
}
@ -18,10 +18,10 @@ static uint64_t load_3(const unsigned char *in) {
static uint64_t load_4(const unsigned char *in) {
uint64_t result;
result = (uint64_t) in[0];
result |= ((uint64_t) in[1]) << 8;
result |= ((uint64_t) in[2]) << 16;
result |= ((uint64_t) in[3]) << 24;
result = in[0];
result |= shlu64(in[1], 8);
result |= shlu64(in[2], 16);
result |= shlu64(in[3], 24);
return result;
}
@ -316,47 +316,47 @@ void fe_frombytes(fe h, const unsigned char *s) {
int64_t carry8;
int64_t carry9;
carry9 = (h9 + (int64_t) (1 << 24)) >> 25;
carry9 = (h9 + (1L << 24)) >> 25;
h0 += carry9 * 19;
h9 -= carry9 << 25;
carry1 = (h1 + (int64_t) (1 << 24)) >> 25;
h9 -= shl64(carry9, 25);
carry1 = (h1 + (1L << 24)) >> 25;
h2 += carry1;
h1 -= carry1 << 25;
carry3 = (h3 + (int64_t) (1 << 24)) >> 25;
h1 -= shl64(carry1, 25);
carry3 = (h3 + (1L << 24)) >> 25;
h4 += carry3;
h3 -= carry3 << 25;
carry5 = (h5 + (int64_t) (1 << 24)) >> 25;
h3 -= shl64(carry3, 25);
carry5 = (h5 + (1L << 24)) >> 25;
h6 += carry5;
h5 -= carry5 << 25;
carry7 = (h7 + (int64_t) (1 << 24)) >> 25;
h5 -= shl64(carry5, 25);
carry7 = (h7 + (1L << 24)) >> 25;
h8 += carry7;
h7 -= carry7 << 25;
carry0 = (h0 + (int64_t) (1 << 25)) >> 26;
h7 -= shl64(carry7, 25);
carry0 = (h0 + (1L << 25)) >> 26;
h1 += carry0;
h0 -= carry0 << 26;
carry2 = (h2 + (int64_t) (1 << 25)) >> 26;
h0 -= shl64(carry0, 26);
carry2 = (h2 + (1L << 25)) >> 26;
h3 += carry2;
h2 -= carry2 << 26;
carry4 = (h4 + (int64_t) (1 << 25)) >> 26;
h2 -= shl64(carry2, 26);
carry4 = (h4 + (1L << 25)) >> 26;
h5 += carry4;
h4 -= carry4 << 26;
carry6 = (h6 + (int64_t) (1 << 25)) >> 26;
h4 -= shl64(carry4, 26);
carry6 = (h6 + (1L << 25)) >> 26;
h7 += carry6;
h6 -= carry6 << 26;
carry8 = (h8 + (int64_t) (1 << 25)) >> 26;
h6 -= shl64(carry6, 26);
carry8 = (h8 + (1L << 25)) >> 26;
h9 += carry8;
h8 -= carry8 << 26;
h8 -= shl64(carry8, 26);
h[0] = (int32_t) h0;
h[1] = (int32_t) h1;
h[2] = (int32_t) h2;
h[3] = (int32_t) h3;
h[4] = (int32_t) h4;
h[5] = (int32_t) h5;
h[6] = (int32_t) h6;
h[7] = (int32_t) h7;
h[8] = (int32_t) h8;
h[9] = (int32_t) h9;
h[0] = h0;
h[1] = h1;
h[2] = h2;
h[3] = h3;
h[4] = h4;
h[5] = h5;
h[6] = h6;
h[7] = h7;
h[8] = h8;
h[9] = h9;
}
@ -709,48 +709,48 @@ void fe_mul(fe h, const fe f, const fe g) {
int64_t carry8;
int64_t carry9;
carry0 = (h0 + (int64_t) (1 << 25)) >> 26;
carry0 = (h0 + (1L << 25)) >> 26;
h1 += carry0;
h0 -= carry0 << 26;
carry4 = (h4 + (int64_t) (1 << 25)) >> 26;
h0 -= shl64(carry0, 26);
carry4 = (h4 + (1L << 25)) >> 26;
h5 += carry4;
h4 -= carry4 << 26;
h4 -= shl64(carry4, 26);
carry1 = (h1 + (int64_t) (1 << 24)) >> 25;
carry1 = (h1 + (1L << 24)) >> 25;
h2 += carry1;
h1 -= carry1 << 25;
carry5 = (h5 + (int64_t) (1 << 24)) >> 25;
h1 -= shl64(carry1, 25);
carry5 = (h5 + (1L << 24)) >> 25;
h6 += carry5;
h5 -= carry5 << 25;
h5 -= shl64(carry5, 25);
carry2 = (h2 + (int64_t) (1 << 25)) >> 26;
carry2 = (h2 + (1L << 25)) >> 26;
h3 += carry2;
h2 -= carry2 << 26;
carry6 = (h6 + (int64_t) (1 << 25)) >> 26;
h2 -= shl64(carry2, 26);
carry6 = (h6 + (1L << 25)) >> 26;
h7 += carry6;
h6 -= carry6 << 26;
h6 -= shl64(carry6, 26);
carry3 = (h3 + (int64_t) (1 << 24)) >> 25;
carry3 = (h3 + (1L << 24)) >> 25;
h4 += carry3;
h3 -= carry3 << 25;
carry7 = (h7 + (int64_t) (1 << 24)) >> 25;
h3 -= shl64(carry3, 25);
carry7 = (h7 + (1L << 24)) >> 25;
h8 += carry7;
h7 -= carry7 << 25;
h7 -= shl64(carry7, 25);
carry4 = (h4 + (int64_t) (1 << 25)) >> 26;
carry4 = (h4 + (1L << 25)) >> 26;
h5 += carry4;
h4 -= carry4 << 26;
carry8 = (h8 + (int64_t) (1 << 25)) >> 26;
h4 -= shl64(carry4, 26);
carry8 = (h8 + (1L << 25)) >> 26;
h9 += carry8;
h8 -= carry8 << 26;
h8 -= shl64(carry8, 26);
carry9 = (h9 + (int64_t) (1 << 24)) >> 25;
carry9 = (h9 + (1L << 24)) >> 25;
h0 += carry9 * 19;
h9 -= carry9 << 25;
h9 -= shl64(carry9, 25);
carry0 = (h0 + (int64_t) (1 << 25)) >> 26;
carry0 = (h0 + (1L << 25)) >> 26;
h1 += carry0;
h0 -= carry0 << 26;
h0 -= shl64(carry0, 26);
h[0] = (int32_t) h0;
h[1] = (int32_t) h1;
@ -808,17 +808,17 @@ void fe_mul121666(fe h, fe f) {
int64_t carry8;
int64_t carry9;
carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= shl64(carry9, 25);
carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= shl64(carry1, 25);
carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= shl64(carry3, 25);
carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= shl64(carry5, 25);
carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= shl64(carry7, 25);
carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= shl64(carry0, 26);
carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= shl64(carry2, 26);
carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= shl64(carry4, 26);
carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= shl64(carry6, 26);
carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= shl64(carry8, 26);
h[0] = h0;
h[1] = h1;
@ -1078,42 +1078,42 @@ void fe_sq(fe h, const fe f) {
int64_t carry7;
int64_t carry8;
int64_t carry9;
carry0 = (h0 + (int64_t) (1 << 25)) >> 26;
carry0 = (h0 + (1L << 25)) >> 26;
h1 += carry0;
h0 -= carry0 << 26;
carry4 = (h4 + (int64_t) (1 << 25)) >> 26;
h0 -= shl64(carry0, 26);
carry4 = (h4 + (1L << 25)) >> 26;
h5 += carry4;
h4 -= carry4 << 26;
carry1 = (h1 + (int64_t) (1 << 24)) >> 25;
h4 -= shl64(carry4, 26);
carry1 = (h1 + (1L << 24)) >> 25;
h2 += carry1;
h1 -= carry1 << 25;
carry5 = (h5 + (int64_t) (1 << 24)) >> 25;
h1 -= shl64(carry1, 25);
carry5 = (h5 + (1L << 24)) >> 25;
h6 += carry5;
h5 -= carry5 << 25;
carry2 = (h2 + (int64_t) (1 << 25)) >> 26;
h5 -= shl64(carry5, 25);
carry2 = (h2 + (1L << 25)) >> 26;
h3 += carry2;
h2 -= carry2 << 26;
carry6 = (h6 + (int64_t) (1 << 25)) >> 26;
h2 -= shl64(carry2, 26);
carry6 = (h6 + (1L << 25)) >> 26;
h7 += carry6;
h6 -= carry6 << 26;
carry3 = (h3 + (int64_t) (1 << 24)) >> 25;
h6 -= shl64(carry6, 26);
carry3 = (h3 + (1L << 24)) >> 25;
h4 += carry3;
h3 -= carry3 << 25;
carry7 = (h7 + (int64_t) (1 << 24)) >> 25;
h3 -= shl64(carry3, 25);
carry7 = (h7 + (1L << 24)) >> 25;
h8 += carry7;
h7 -= carry7 << 25;
carry4 = (h4 + (int64_t) (1 << 25)) >> 26;
h7 -= shl64(carry7, 25);
carry4 = (h4 + (1L << 25)) >> 26;
h5 += carry4;
h4 -= carry4 << 26;
carry8 = (h8 + (int64_t) (1 << 25)) >> 26;
h4 -= shl64(carry4, 26);
carry8 = (h8 + (1L << 25)) >> 26;
h9 += carry8;
h8 -= carry8 << 26;
carry9 = (h9 + (int64_t) (1 << 24)) >> 25;
h8 -= shl64(carry8, 26);
carry9 = (h9 + (1L << 24)) >> 25;
h0 += carry9 * 19;
h9 -= carry9 << 25;
carry0 = (h0 + (int64_t) (1 << 25)) >> 26;
h9 -= shl64(carry9, 25);
carry0 = (h0 + (1L << 25)) >> 26;
h1 += carry0;
h0 -= carry0 << 26;
h0 -= shl64(carry0, 26);
h[0] = (int32_t) h0;
h[1] = (int32_t) h1;
h[2] = (int32_t) h2;
@ -1251,42 +1251,42 @@ void fe_sq2(fe h, const fe f) {
h7 += h7;
h8 += h8;
h9 += h9;
carry0 = (h0 + (int64_t) (1 << 25)) >> 26;
carry0 = (h0 + (1L << 25)) >> 26;
h1 += carry0;
h0 -= carry0 << 26;
carry4 = (h4 + (int64_t) (1 << 25)) >> 26;
h0 -= shl64(carry0, 26);
carry4 = (h4 + (1L << 25)) >> 26;
h5 += carry4;
h4 -= carry4 << 26;
carry1 = (h1 + (int64_t) (1 << 24)) >> 25;
h4 -= shl64(carry4, 26);
carry1 = (h1 + (1L << 24)) >> 25;
h2 += carry1;
h1 -= carry1 << 25;
carry5 = (h5 + (int64_t) (1 << 24)) >> 25;
h1 -= shl64(carry1, 25);
carry5 = (h5 + (1L << 24)) >> 25;
h6 += carry5;
h5 -= carry5 << 25;
carry2 = (h2 + (int64_t) (1 << 25)) >> 26;
h5 -= shl64(carry5, 25);
carry2 = (h2 + (1L << 25)) >> 26;
h3 += carry2;
h2 -= carry2 << 26;
carry6 = (h6 + (int64_t) (1 << 25)) >> 26;
h2 -= shl64(carry2, 26);
carry6 = (h6 + (1L << 25)) >> 26;
h7 += carry6;
h6 -= carry6 << 26;
carry3 = (h3 + (int64_t) (1 << 24)) >> 25;
h6 -= shl64(carry6, 26);
carry3 = (h3 + (1L << 24)) >> 25;
h4 += carry3;
h3 -= carry3 << 25;
carry7 = (h7 + (int64_t) (1 << 24)) >> 25;
h3 -= shl64(carry3, 25);
carry7 = (h7 + (1L << 24)) >> 25;
h8 += carry7;
h7 -= carry7 << 25;
carry4 = (h4 + (int64_t) (1 << 25)) >> 26;
h7 -= shl64(carry7, 25);
carry4 = (h4 + (1L << 25)) >> 26;
h5 += carry4;
h4 -= carry4 << 26;
carry8 = (h8 + (int64_t) (1 << 25)) >> 26;
h4 -= shl64(carry4, 26);
carry8 = (h8 + (1L << 25)) >> 26;
h9 += carry8;
h8 -= carry8 << 26;
carry9 = (h9 + (int64_t) (1 << 24)) >> 25;
h8 -= shl64(carry8, 26);
carry9 = (h9 + (1L << 24)) >> 25;
h0 += carry9 * 19;
h9 -= carry9 << 25;
carry0 = (h0 + (int64_t) (1 << 25)) >> 26;
h9 -= shl64(carry9, 25);
carry0 = (h0 + (1L << 25)) >> 26;
h1 += carry0;
h0 -= carry0 << 26;
h0 -= shl64(carry0, 26);
h[0] = (int32_t) h0;
h[1] = (int32_t) h1;
h[2] = (int32_t) h2;
@ -1421,33 +1421,33 @@ void fe_tobytes(unsigned char *s, const fe h) {
/* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */
carry0 = h0 >> 26;
h1 += carry0;
h0 -= carry0 << 26;
h0 -= shl32(carry0, 26);
carry1 = h1 >> 25;
h2 += carry1;
h1 -= carry1 << 25;
h1 -= shl32(carry1, 25);
carry2 = h2 >> 26;
h3 += carry2;
h2 -= carry2 << 26;
h2 -= shl32(carry2, 26);
carry3 = h3 >> 25;
h4 += carry3;
h3 -= carry3 << 25;
h3 -= shl32(carry3, 25);
carry4 = h4 >> 26;
h5 += carry4;
h4 -= carry4 << 26;
h4 -= shl32(carry4, 26);
carry5 = h5 >> 25;
h6 += carry5;
h5 -= carry5 << 25;
h5 -= shl32(carry5, 25);
carry6 = h6 >> 26;
h7 += carry6;
h6 -= carry6 << 26;
h6 -= shl32(carry6, 26);
carry7 = h7 >> 25;
h8 += carry7;
h7 -= carry7 << 25;
h7 -= shl32(carry7, 25);
carry8 = h8 >> 26;
h9 += carry8;
h8 -= carry8 << 26;
h8 -= shl32(carry8, 26);
carry9 = h9 >> 25;
h9 -= carry9 << 25;
h9 -= shl32(carry9, 25);
/* h10 = carry9 */
/*
@ -1459,32 +1459,32 @@ void fe_tobytes(unsigned char *s, const fe h) {
s[0] = (unsigned char) (h0 >> 0);
s[1] = (unsigned char) (h0 >> 8);
s[2] = (unsigned char) (h0 >> 16);
s[3] = (unsigned char) ((h0 >> 24) | (h1 << 2));
s[3] = (unsigned char) ((h0 >> 24) | shl32(h1, 2));
s[4] = (unsigned char) (h1 >> 6);
s[5] = (unsigned char) (h1 >> 14);
s[6] = (unsigned char) ((h1 >> 22) | (h2 << 3));
s[6] = (unsigned char) ((h1 >> 22) | shl32(h2, 3));
s[7] = (unsigned char) (h2 >> 5);
s[8] = (unsigned char) (h2 >> 13);
s[9] = (unsigned char) ((h2 >> 21) | (h3 << 5));
s[9] = (unsigned char) ((h2 >> 21) | shl32(h3, 5));
s[10] = (unsigned char) (h3 >> 3);
s[11] = (unsigned char) (h3 >> 11);
s[12] = (unsigned char) ((h3 >> 19) | (h4 << 6));
s[12] = (unsigned char) ((h3 >> 19) | shl32(h4, 6));
s[13] = (unsigned char) (h4 >> 2);
s[14] = (unsigned char) (h4 >> 10);
s[15] = (unsigned char) (h4 >> 18);
s[16] = (unsigned char) (h5 >> 0);
s[17] = (unsigned char) (h5 >> 8);
s[18] = (unsigned char) (h5 >> 16);
s[19] = (unsigned char) ((h5 >> 24) | (h6 << 1));
s[19] = (unsigned char) ((h5 >> 24) | shl32(h6, 1));
s[20] = (unsigned char) (h6 >> 7);
s[21] = (unsigned char) (h6 >> 15);
s[22] = (unsigned char) ((h6 >> 23) | (h7 << 3));
s[22] = (unsigned char) ((h6 >> 23) | shl32(h7, 3));
s[23] = (unsigned char) (h7 >> 5);
s[24] = (unsigned char) (h7 >> 13);
s[25] = (unsigned char) ((h7 >> 21) | (h8 << 4));
s[25] = (unsigned char) ((h7 >> 21) | shl32(h8, 4));
s[26] = (unsigned char) (h8 >> 4);
s[27] = (unsigned char) (h8 >> 12);
s[28] = (unsigned char) ((h8 >> 20) | (h9 << 6));
s[28] = (unsigned char) ((h8 >> 20) | shl32(h9, 6));
s[29] = (unsigned char) (h9 >> 2);
s[30] = (unsigned char) (h9 >> 10);
s[31] = (unsigned char) (h9 >> 18);

View file

@ -4,6 +4,9 @@
Not a compatible replacement for <stdint.h>, do not blindly use it as such.
*/
#ifndef __TINC_FIXEDINT_H__
#define __TINC_FIXEDINT_H__
#if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined(__WATCOMC__) && (defined(_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_) || defined(__UINT_FAST64_TYPE__)) )) && !defined(FIXEDINT_H_INCLUDED)
#include <stdint.h>
#define FIXEDINT_H_INCLUDED
@ -68,3 +71,21 @@
#define INT64_C(v) v ##I64
#endif
#endif
static inline unsigned char shlu8(unsigned char a, uint32_t b) {
return a << b;
}
static inline int32_t shl32(uint32_t a, uint32_t b) {
return a << b;
}
static inline int64_t shl64(uint64_t a, uint32_t b) {
return a << b;
}
static inline uint64_t shlu64(uint64_t a, uint32_t b) {
return a << b;
}
#endif

View file

@ -356,7 +356,7 @@ static void cmov(ge_precomp *t, ge_precomp *u, unsigned char b) {
static void select(ge_precomp *t, int pos, signed char b) {
ge_precomp minust;
unsigned char bnegative = negative(b);
unsigned char babs = b - (((-bnegative) & b) << 1);
unsigned char babs = b - shlu8(((-bnegative) & b), 1);
fe_1(t->yplusx);
fe_1(t->yminusx);
fe_0(t->xy2d);
@ -404,7 +404,7 @@ void ge_scalarmult_base(ge_p3 *h, const unsigned char *a) {
e[i] += carry;
carry = e[i] + 8;
carry >>= 4;
e[i] -= carry << 4;
e[i] -= shl32(carry, 4);
}
e[63] += carry;

View file

@ -4,9 +4,9 @@
static uint64_t load_3(const unsigned char *in) {
uint64_t result;
result = (uint64_t) in[0];
result |= ((uint64_t) in[1]) << 8;
result |= ((uint64_t) in[2]) << 16;
result = in[0];
result |= shlu64(in[1], 8);
result |= shlu64(in[2], 16);
return result;
}
@ -14,10 +14,10 @@ static uint64_t load_3(const unsigned char *in) {
static uint64_t load_4(const unsigned char *in) {
uint64_t result;
result = (uint64_t) in[0];
result |= ((uint64_t) in[1]) << 8;
result |= ((uint64_t) in[2]) << 16;
result |= ((uint64_t) in[3]) << 24;
result = in[0];
result |= shlu64(in[1], 8);
result |= shlu64(in[2], 16);
result |= shlu64(in[3], 24);
return result;
}
@ -119,37 +119,37 @@ void sc_reduce(unsigned char *s) {
s18 = 0;
carry6 = (s6 + (1 << 20)) >> 21;
s7 += carry6;
s6 -= carry6 << 21;
s6 -= shl64(carry6, 21);
carry8 = (s8 + (1 << 20)) >> 21;
s9 += carry8;
s8 -= carry8 << 21;
s8 -= shl64(carry8, 21);
carry10 = (s10 + (1 << 20)) >> 21;
s11 += carry10;
s10 -= carry10 << 21;
s10 -= shl64(carry10, 21);
carry12 = (s12 + (1 << 20)) >> 21;
s13 += carry12;
s12 -= carry12 << 21;
s12 -= shl64(carry12, 21);
carry14 = (s14 + (1 << 20)) >> 21;
s15 += carry14;
s14 -= carry14 << 21;
s14 -= shl64(carry14, 21);
carry16 = (s16 + (1 << 20)) >> 21;
s17 += carry16;
s16 -= carry16 << 21;
s16 -= shl64(carry16, 21);
carry7 = (s7 + (1 << 20)) >> 21;
s8 += carry7;
s7 -= carry7 << 21;
s7 -= shl64(carry7, 21);
carry9 = (s9 + (1 << 20)) >> 21;
s10 += carry9;
s9 -= carry9 << 21;
s9 -= shl64(carry9, 21);
carry11 = (s11 + (1 << 20)) >> 21;
s12 += carry11;
s11 -= carry11 << 21;
s11 -= shl64(carry11, 21);
carry13 = (s13 + (1 << 20)) >> 21;
s14 += carry13;
s13 -= carry13 << 21;
s13 -= shl64(carry13, 21);
carry15 = (s15 + (1 << 20)) >> 21;
s16 += carry15;
s15 -= carry15 << 21;
s15 -= shl64(carry15, 21);
s5 += s17 * 666643;
s6 += s17 * 470296;
s7 += s17 * 654183;
@ -194,40 +194,40 @@ void sc_reduce(unsigned char *s) {
s12 = 0;
carry0 = (s0 + (1 << 20)) >> 21;
s1 += carry0;
s0 -= carry0 << 21;
s0 -= shl64(carry0, 21);
carry2 = (s2 + (1 << 20)) >> 21;
s3 += carry2;
s2 -= carry2 << 21;
s2 -= shl64(carry2, 21);
carry4 = (s4 + (1 << 20)) >> 21;
s5 += carry4;
s4 -= carry4 << 21;
s4 -= shl64(carry4, 21);
carry6 = (s6 + (1 << 20)) >> 21;
s7 += carry6;
s6 -= carry6 << 21;
s6 -= shl64(carry6, 21);
carry8 = (s8 + (1 << 20)) >> 21;
s9 += carry8;
s8 -= carry8 << 21;
s8 -= shl64(carry8, 21);
carry10 = (s10 + (1 << 20)) >> 21;
s11 += carry10;
s10 -= carry10 << 21;
s10 -= shl64(carry10, 21);
carry1 = (s1 + (1 << 20)) >> 21;
s2 += carry1;
s1 -= carry1 << 21;
s1 -= shl64(carry1, 21);
carry3 = (s3 + (1 << 20)) >> 21;
s4 += carry3;
s3 -= carry3 << 21;
s3 -= shl64(carry3, 21);
carry5 = (s5 + (1 << 20)) >> 21;
s6 += carry5;
s5 -= carry5 << 21;
s5 -= shl64(carry5, 21);
carry7 = (s7 + (1 << 20)) >> 21;
s8 += carry7;
s7 -= carry7 << 21;
s7 -= shl64(carry7, 21);
carry9 = (s9 + (1 << 20)) >> 21;
s10 += carry9;
s9 -= carry9 << 21;
s9 -= shl64(carry9, 21);
carry11 = (s11 + (1 << 20)) >> 21;
s12 += carry11;
s11 -= carry11 << 21;
s11 -= shl64(carry11, 21);
s0 += s12 * 666643;
s1 += s12 * 470296;
s2 += s12 * 654183;
@ -237,40 +237,40 @@ void sc_reduce(unsigned char *s) {
s12 = 0;
carry0 = s0 >> 21;
s1 += carry0;
s0 -= carry0 << 21;
s0 -= shl64(carry0, 21);
carry1 = s1 >> 21;
s2 += carry1;
s1 -= carry1 << 21;
s1 -= shl64(carry1, 21);
carry2 = s2 >> 21;
s3 += carry2;
s2 -= carry2 << 21;
s2 -= shl64(carry2, 21);
carry3 = s3 >> 21;
s4 += carry3;
s3 -= carry3 << 21;
s3 -= shl64(carry3, 21);
carry4 = s4 >> 21;
s5 += carry4;
s4 -= carry4 << 21;
s4 -= shl64(carry4, 21);
carry5 = s5 >> 21;
s6 += carry5;
s5 -= carry5 << 21;
s5 -= shl64(carry5, 21);
carry6 = s6 >> 21;
s7 += carry6;
s6 -= carry6 << 21;
s6 -= shl64(carry6, 21);
carry7 = s7 >> 21;
s8 += carry7;
s7 -= carry7 << 21;
s7 -= shl64(carry7, 21);
carry8 = s8 >> 21;
s9 += carry8;
s8 -= carry8 << 21;
s8 -= shl64(carry8, 21);
carry9 = s9 >> 21;
s10 += carry9;
s9 -= carry9 << 21;
s9 -= shl64(carry9, 21);
carry10 = s10 >> 21;
s11 += carry10;
s10 -= carry10 << 21;
s10 -= shl64(carry10, 21);
carry11 = s11 >> 21;
s12 += carry11;
s11 -= carry11 << 21;
s11 -= shl64(carry11, 21);
s0 += s12 * 666643;
s1 += s12 * 470296;
s2 += s12 * 654183;
@ -280,67 +280,67 @@ void sc_reduce(unsigned char *s) {
s12 = 0;
carry0 = s0 >> 21;
s1 += carry0;
s0 -= carry0 << 21;
s0 -= shl64(carry0, 21);
carry1 = s1 >> 21;
s2 += carry1;
s1 -= carry1 << 21;
s1 -= shl64(carry1, 21);
carry2 = s2 >> 21;
s3 += carry2;
s2 -= carry2 << 21;
s2 -= shl64(carry2, 21);
carry3 = s3 >> 21;
s4 += carry3;
s3 -= carry3 << 21;
s3 -= shl64(carry3, 21);
carry4 = s4 >> 21;
s5 += carry4;
s4 -= carry4 << 21;
s4 -= shl64(carry4, 21);
carry5 = s5 >> 21;
s6 += carry5;
s5 -= carry5 << 21;
s5 -= shl64(carry5, 21);
carry6 = s6 >> 21;
s7 += carry6;
s6 -= carry6 << 21;
s6 -= shl64(carry6, 21);
carry7 = s7 >> 21;
s8 += carry7;
s7 -= carry7 << 21;
s7 -= shl64(carry7, 21);
carry8 = s8 >> 21;
s9 += carry8;
s8 -= carry8 << 21;
s8 -= shl64(carry8, 21);
carry9 = s9 >> 21;
s10 += carry9;
s9 -= carry9 << 21;
s9 -= shl64(carry9, 21);
carry10 = s10 >> 21;
s11 += carry10;
s10 -= carry10 << 21;
s10 -= shl64(carry10, 21);
s[0] = (unsigned char) (s0 >> 0);
s[1] = (unsigned char) (s0 >> 8);
s[2] = (unsigned char) ((s0 >> 16) | (s1 << 5));
s[2] = (unsigned char) ((s0 >> 16) | shl64(s1, 5));
s[3] = (unsigned char) (s1 >> 3);
s[4] = (unsigned char) (s1 >> 11);
s[5] = (unsigned char) ((s1 >> 19) | (s2 << 2));
s[5] = (unsigned char) ((s1 >> 19) | shl64(s2, 2));
s[6] = (unsigned char) (s2 >> 6);
s[7] = (unsigned char) ((s2 >> 14) | (s3 << 7));
s[7] = (unsigned char) ((s2 >> 14) | shl64(s3, 7));
s[8] = (unsigned char) (s3 >> 1);
s[9] = (unsigned char) (s3 >> 9);
s[10] = (unsigned char) ((s3 >> 17) | (s4 << 4));
s[10] = (unsigned char) ((s3 >> 17) | shl64(s4, 4));
s[11] = (unsigned char) (s4 >> 4);
s[12] = (unsigned char) (s4 >> 12);
s[13] = (unsigned char) ((s4 >> 20) | (s5 << 1));
s[13] = (unsigned char) ((s4 >> 20) | shl64(s5, 1));
s[14] = (unsigned char) (s5 >> 7);
s[15] = (unsigned char) ((s5 >> 15) | (s6 << 6));
s[15] = (unsigned char) ((s5 >> 15) | shl64(s6, 6));
s[16] = (unsigned char) (s6 >> 2);
s[17] = (unsigned char) (s6 >> 10);
s[18] = (unsigned char) ((s6 >> 18) | (s7 << 3));
s[18] = (unsigned char) ((s6 >> 18) | shl64(s7, 3));
s[19] = (unsigned char) (s7 >> 5);
s[20] = (unsigned char) (s7 >> 13);
s[21] = (unsigned char) (s8 >> 0);
s[22] = (unsigned char) (s8 >> 8);
s[23] = (unsigned char) ((s8 >> 16) | (s9 << 5));
s[23] = (unsigned char) ((s8 >> 16) | shl64(s9, 5));
s[24] = (unsigned char) (s9 >> 3);
s[25] = (unsigned char) (s9 >> 11);
s[26] = (unsigned char) ((s9 >> 19) | (s10 << 2));
s[26] = (unsigned char) ((s9 >> 19) | shl64(s10, 2));
s[27] = (unsigned char) (s10 >> 6);
s[28] = (unsigned char) ((s10 >> 14) | (s11 << 7));
s[28] = (unsigned char) ((s10 >> 14) | shl64(s11, 7));
s[29] = (unsigned char) (s11 >> 1);
s[30] = (unsigned char) (s11 >> 9);
s[31] = (unsigned char) (s11 >> 17);
@ -470,73 +470,73 @@ void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b,
s23 = 0;
carry0 = (s0 + (1 << 20)) >> 21;
s1 += carry0;
s0 -= carry0 << 21;
s0 -= shl64(carry0, 21);
carry2 = (s2 + (1 << 20)) >> 21;
s3 += carry2;
s2 -= carry2 << 21;
s2 -= shl64(carry2, 21);
carry4 = (s4 + (1 << 20)) >> 21;
s5 += carry4;
s4 -= carry4 << 21;
s4 -= shl64(carry4, 21);
carry6 = (s6 + (1 << 20)) >> 21;
s7 += carry6;
s6 -= carry6 << 21;
s6 -= shl64(carry6, 21);
carry8 = (s8 + (1 << 20)) >> 21;
s9 += carry8;
s8 -= carry8 << 21;
s8 -= shl64(carry8, 21);
carry10 = (s10 + (1 << 20)) >> 21;
s11 += carry10;
s10 -= carry10 << 21;
s10 -= shl64(carry10, 21);
carry12 = (s12 + (1 << 20)) >> 21;
s13 += carry12;
s12 -= carry12 << 21;
s12 -= shl64(carry12, 21);
carry14 = (s14 + (1 << 20)) >> 21;
s15 += carry14;
s14 -= carry14 << 21;
s14 -= shl64(carry14, 21);
carry16 = (s16 + (1 << 20)) >> 21;
s17 += carry16;
s16 -= carry16 << 21;
s16 -= shl64(carry16, 21);
carry18 = (s18 + (1 << 20)) >> 21;
s19 += carry18;
s18 -= carry18 << 21;
s18 -= shl64(carry18, 21);
carry20 = (s20 + (1 << 20)) >> 21;
s21 += carry20;
s20 -= carry20 << 21;
s20 -= shl64(carry20, 21);
carry22 = (s22 + (1 << 20)) >> 21;
s23 += carry22;
s22 -= carry22 << 21;
s22 -= shl64(carry22, 21);
carry1 = (s1 + (1 << 20)) >> 21;
s2 += carry1;
s1 -= carry1 << 21;
s1 -= shl64(carry1, 21);
carry3 = (s3 + (1 << 20)) >> 21;
s4 += carry3;
s3 -= carry3 << 21;
s3 -= shl64(carry3, 21);
carry5 = (s5 + (1 << 20)) >> 21;
s6 += carry5;
s5 -= carry5 << 21;
s5 -= shl64(carry5, 21);
carry7 = (s7 + (1 << 20)) >> 21;
s8 += carry7;
s7 -= carry7 << 21;
s7 -= shl64(carry7, 21);
carry9 = (s9 + (1 << 20)) >> 21;
s10 += carry9;
s9 -= carry9 << 21;
s9 -= shl64(carry9, 21);
carry11 = (s11 + (1 << 20)) >> 21;
s12 += carry11;
s11 -= carry11 << 21;
s11 -= shl64(carry11, 21);
carry13 = (s13 + (1 << 20)) >> 21;
s14 += carry13;
s13 -= carry13 << 21;
s13 -= shl64(carry13, 21);
carry15 = (s15 + (1 << 20)) >> 21;
s16 += carry15;
s15 -= carry15 << 21;
s15 -= shl64(carry15, 21);
carry17 = (s17 + (1 << 20)) >> 21;
s18 += carry17;
s17 -= carry17 << 21;
s17 -= shl64(carry17, 21);
carry19 = (s19 + (1 << 20)) >> 21;
s20 += carry19;
s19 -= carry19 << 21;
s19 -= shl64(carry19, 21);
carry21 = (s21 + (1 << 20)) >> 21;
s22 += carry21;
s21 -= carry21 << 21;
s21 -= shl64(carry21, 21);
s11 += s23 * 666643;
s12 += s23 * 470296;
s13 += s23 * 654183;
@ -581,37 +581,37 @@ void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b,
s18 = 0;
carry6 = (s6 + (1 << 20)) >> 21;
s7 += carry6;
s6 -= carry6 << 21;
s6 -= shl64(carry6, 21);
carry8 = (s8 + (1 << 20)) >> 21;
s9 += carry8;
s8 -= carry8 << 21;
s8 -= shl64(carry8, 21);
carry10 = (s10 + (1 << 20)) >> 21;
s11 += carry10;
s10 -= carry10 << 21;
s10 -= shl64(carry10, 21);
carry12 = (s12 + (1 << 20)) >> 21;
s13 += carry12;
s12 -= carry12 << 21;
s12 -= shl64(carry12, 21);
carry14 = (s14 + (1 << 20)) >> 21;
s15 += carry14;
s14 -= carry14 << 21;
s14 -= shl64(carry14, 21);
carry16 = (s16 + (1 << 20)) >> 21;
s17 += carry16;
s16 -= carry16 << 21;
s16 -= shl64(carry16, 21);
carry7 = (s7 + (1 << 20)) >> 21;
s8 += carry7;
s7 -= carry7 << 21;
s7 -= shl64(carry7, 21);
carry9 = (s9 + (1 << 20)) >> 21;
s10 += carry9;
s9 -= carry9 << 21;
s9 -= shl64(carry9, 21);
carry11 = (s11 + (1 << 20)) >> 21;
s12 += carry11;
s11 -= carry11 << 21;
s11 -= shl64(carry11, 21);
carry13 = (s13 + (1 << 20)) >> 21;
s14 += carry13;
s13 -= carry13 << 21;
s13 -= shl64(carry13, 21);
carry15 = (s15 + (1 << 20)) >> 21;
s16 += carry15;
s15 -= carry15 << 21;
s15 -= shl64(carry15, 21);
s5 += s17 * 666643;
s6 += s17 * 470296;
s7 += s17 * 654183;
@ -656,40 +656,40 @@ void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b,
s12 = 0;
carry0 = (s0 + (1 << 20)) >> 21;
s1 += carry0;
s0 -= carry0 << 21;
s0 -= shl64(carry0, 21);
carry2 = (s2 + (1 << 20)) >> 21;
s3 += carry2;
s2 -= carry2 << 21;
s2 -= shl64(carry2, 21);
carry4 = (s4 + (1 << 20)) >> 21;
s5 += carry4;
s4 -= carry4 << 21;
s4 -= shl64(carry4, 21);
carry6 = (s6 + (1 << 20)) >> 21;
s7 += carry6;
s6 -= carry6 << 21;
s6 -= shl64(carry6, 21);
carry8 = (s8 + (1 << 20)) >> 21;
s9 += carry8;
s8 -= carry8 << 21;
s8 -= shl64(carry8, 21);
carry10 = (s10 + (1 << 20)) >> 21;
s11 += carry10;
s10 -= carry10 << 21;
s10 -= shl64(carry10, 21);
carry1 = (s1 + (1 << 20)) >> 21;
s2 += carry1;
s1 -= carry1 << 21;
s1 -= shl64(carry1, 21);
carry3 = (s3 + (1 << 20)) >> 21;
s4 += carry3;
s3 -= carry3 << 21;
s3 -= shl64(carry3, 21);
carry5 = (s5 + (1 << 20)) >> 21;
s6 += carry5;
s5 -= carry5 << 21;
s5 -= shl64(carry5, 21);
carry7 = (s7 + (1 << 20)) >> 21;
s8 += carry7;
s7 -= carry7 << 21;
s7 -= shl64(carry7, 21);
carry9 = (s9 + (1 << 20)) >> 21;
s10 += carry9;
s9 -= carry9 << 21;
s9 -= shl64(carry9, 21);
carry11 = (s11 + (1 << 20)) >> 21;
s12 += carry11;
s11 -= carry11 << 21;
s11 -= shl64(carry11, 21);
s0 += s12 * 666643;
s1 += s12 * 470296;
s2 += s12 * 654183;
@ -699,40 +699,40 @@ void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b,
s12 = 0;
carry0 = s0 >> 21;
s1 += carry0;
s0 -= carry0 << 21;
s0 -= shl64(carry0, 21);
carry1 = s1 >> 21;
s2 += carry1;
s1 -= carry1 << 21;
s1 -= shl64(carry1, 21);
carry2 = s2 >> 21;
s3 += carry2;
s2 -= carry2 << 21;
s2 -= shl64(carry2, 21);
carry3 = s3 >> 21;
s4 += carry3;
s3 -= carry3 << 21;
s3 -= shl64(carry3, 21);
carry4 = s4 >> 21;
s5 += carry4;
s4 -= carry4 << 21;
s4 -= shl64(carry4, 21);
carry5 = s5 >> 21;
s6 += carry5;
s5 -= carry5 << 21;
s5 -= shl64(carry5, 21);
carry6 = s6 >> 21;
s7 += carry6;
s6 -= carry6 << 21;
s6 -= shl64(carry6, 21);
carry7 = s7 >> 21;
s8 += carry7;
s7 -= carry7 << 21;
s7 -= shl64(carry7, 21);
carry8 = s8 >> 21;
s9 += carry8;
s8 -= carry8 << 21;
s8 -= shl64(carry8, 21);
carry9 = s9 >> 21;
s10 += carry9;
s9 -= carry9 << 21;
s9 -= shl64(carry9, 21);
carry10 = s10 >> 21;
s11 += carry10;
s10 -= carry10 << 21;
s10 -= shl64(carry10, 21);
carry11 = s11 >> 21;
s12 += carry11;
s11 -= carry11 << 21;
s11 -= shl64(carry11, 21);
s0 += s12 * 666643;
s1 += s12 * 470296;
s2 += s12 * 654183;
@ -742,67 +742,67 @@ void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b,
s12 = 0;
carry0 = s0 >> 21;
s1 += carry0;
s0 -= carry0 << 21;
s0 -= shl64(carry0, 21);
carry1 = s1 >> 21;
s2 += carry1;
s1 -= carry1 << 21;
s1 -= shl64(carry1, 21);
carry2 = s2 >> 21;
s3 += carry2;
s2 -= carry2 << 21;
s2 -= shl64(carry2, 21);
carry3 = s3 >> 21;
s4 += carry3;
s3 -= carry3 << 21;
s3 -= shl64(carry3, 21);
carry4 = s4 >> 21;
s5 += carry4;
s4 -= carry4 << 21;
s4 -= shl64(carry4, 21);
carry5 = s5 >> 21;
s6 += carry5;
s5 -= carry5 << 21;
s5 -= shl64(carry5, 21);
carry6 = s6 >> 21;
s7 += carry6;
s6 -= carry6 << 21;
s6 -= shl64(carry6, 21);
carry7 = s7 >> 21;
s8 += carry7;
s7 -= carry7 << 21;
s7 -= shl64(carry7, 21);
carry8 = s8 >> 21;
s9 += carry8;
s8 -= carry8 << 21;
s8 -= shl64(carry8, 21);
carry9 = s9 >> 21;
s10 += carry9;
s9 -= carry9 << 21;
s9 -= shl64(carry9, 21);
carry10 = s10 >> 21;
s11 += carry10;
s10 -= carry10 << 21;
s10 -= shl64(carry10, 21);
s[0] = (unsigned char) (s0 >> 0);
s[1] = (unsigned char) (s0 >> 8);
s[2] = (unsigned char) ((s0 >> 16) | (s1 << 5));
s[2] = (unsigned char) ((s0 >> 16) | shl64(s1, 5));
s[3] = (unsigned char) (s1 >> 3);
s[4] = (unsigned char) (s1 >> 11);
s[5] = (unsigned char) ((s1 >> 19) | (s2 << 2));
s[5] = (unsigned char) ((s1 >> 19) | shl64(s2, 2));
s[6] = (unsigned char) (s2 >> 6);
s[7] = (unsigned char) ((s2 >> 14) | (s3 << 7));
s[7] = (unsigned char) ((s2 >> 14) | shl64(s3, 7));
s[8] = (unsigned char) (s3 >> 1);
s[9] = (unsigned char) (s3 >> 9);
s[10] = (unsigned char) ((s3 >> 17) | (s4 << 4));
s[10] = (unsigned char) ((s3 >> 17) | shl64(s4, 4));
s[11] = (unsigned char) (s4 >> 4);
s[12] = (unsigned char) (s4 >> 12);
s[13] = (unsigned char) ((s4 >> 20) | (s5 << 1));
s[13] = (unsigned char) ((s4 >> 20) | shl64(s5, 1));
s[14] = (unsigned char) (s5 >> 7);
s[15] = (unsigned char) ((s5 >> 15) | (s6 << 6));
s[15] = (unsigned char) ((s5 >> 15) | shl64(s6, 6));
s[16] = (unsigned char) (s6 >> 2);
s[17] = (unsigned char) (s6 >> 10);
s[18] = (unsigned char) ((s6 >> 18) | (s7 << 3));
s[18] = (unsigned char) ((s6 >> 18) | shl64(s7, 3));
s[19] = (unsigned char) (s7 >> 5);
s[20] = (unsigned char) (s7 >> 13);
s[21] = (unsigned char) (s8 >> 0);
s[22] = (unsigned char) (s8 >> 8);
s[23] = (unsigned char) ((s8 >> 16) | (s9 << 5));
s[23] = (unsigned char) ((s8 >> 16) | shl64(s9, 5));
s[24] = (unsigned char) (s9 >> 3);
s[25] = (unsigned char) (s9 >> 11);
s[26] = (unsigned char) ((s9 >> 19) | (s10 << 2));
s[26] = (unsigned char) ((s9 >> 19) | shl64(s10, 2));
s[27] = (unsigned char) (s10 >> 6);
s[28] = (unsigned char) ((s10 >> 14) | (s11 << 7));
s[28] = (unsigned char) ((s10 >> 14) | shl64(s11, 7));
s[29] = (unsigned char) (s11 >> 1);
s[30] = (unsigned char) (s11 >> 9);
s[31] = (unsigned char) (s11 >> 17);

View file

@ -88,7 +88,7 @@ static const uint64_t K[80] = {
#endif
/* compress 1024-bits */
static int sha512_compress(sha512_context *md, unsigned char *buf)
static int sha512_compress(sha512_context *md, const unsigned char *buf)
{
uint64_t S[8], W[80], t0, t1;
int i;
@ -168,8 +168,9 @@ int sha512_init(sha512_context * md) {
@param inlen The length of the data (octets)
@return 0 if successful
*/
int sha512_update (sha512_context * md, const unsigned char *in, size_t inlen)
int sha512_update(sha512_context *md, const void *vin, size_t inlen)
{
const unsigned char *in = vin;
size_t n;
size_t i;
int err;
@ -180,7 +181,7 @@ int sha512_update (sha512_context * md, const unsigned char *in, size_t inlen)
}
while (inlen > 0) {
if (md->curlen == 0 && inlen >= 128) {
if ((err = sha512_compress (md, (unsigned char *)in)) != 0) {
if ((err = sha512_compress (md, in)) != 0) {
return err;
}
md->length += 128 * 8;
@ -215,9 +216,10 @@ int sha512_update (sha512_context * md, const unsigned char *in, size_t inlen)
@param out [out] The destination of the hash (64 bytes)
@return 0 if successful
*/
int sha512_final(sha512_context * md, unsigned char *out)
{
int sha512_final(sha512_context * md, void *vout)
{
int i;
unsigned char *out = vout;
if (md == NULL) return 1;
if (out == NULL) return 1;
@ -248,23 +250,23 @@ int sha512_update (sha512_context * md, const unsigned char *in, size_t inlen)
* note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash
* > 2^64 bits of data... :-)
*/
while (md->curlen < 120) {
while (md->curlen < 120) {
md->buf[md->curlen++] = (unsigned char)0;
}
}
/* store length */
STORE64H(md->length, md->buf+120);
sha512_compress(md, md->buf);
STORE64H(md->length, md->buf+120);
sha512_compress(md, md->buf);
/* copy output */
for (i = 0; i < 8; i++) {
for (i = 0; i < 8; i++) {
STORE64H(md->state[i], out+(8*i));
}
return 0;
}
return 0;
}
int sha512(const unsigned char *message, size_t message_len, unsigned char *out)
int sha512(const void *message, size_t message_len, void *out)
{
sha512_context ctx;
int ret;

View file

@ -14,8 +14,8 @@ typedef struct sha512_context_ {
int sha512_init(sha512_context * md);
int sha512_final(sha512_context * md, unsigned char *out);
int sha512_update(sha512_context * md, const unsigned char *in, size_t inlen);
int sha512(const unsigned char *message, size_t message_len, unsigned char *out);
int sha512_final(sha512_context * md, void *out);
int sha512_update(sha512_context * md, const void *in, size_t inlen);
int sha512(const void *message, size_t message_len, void *out);
#endif

View file

@ -75,6 +75,7 @@ edge_t *new_edge(void) {
void free_edge(edge_t *e) {
sockaddrfree(&e->address);
sockaddrfree(&e->local_address);
free(e);
}

View file

@ -50,7 +50,7 @@ struct ether_header {
uint8_t ether_dhost[ETH_ALEN];
uint8_t ether_shost[ETH_ALEN];
uint16_t ether_type;
} __attribute__ ((__packed__));
} __attribute__ ((__gcc_struct__, __packed__));
#endif
#ifndef HAVE_STRUCT_ARPHDR
@ -60,7 +60,7 @@ struct arphdr {
uint8_t ar_hln;
uint8_t ar_pln;
uint16_t ar_op;
} __attribute__ ((__packed__));
} __attribute__ ((__gcc_struct__, __packed__));
#define ARPOP_REQUEST 1
#define ARPOP_REPLY 2
@ -78,7 +78,7 @@ struct ether_arp {
uint8_t arp_spa[4];
uint8_t arp_tha[ETH_ALEN];
uint8_t arp_tpa[4];
} __attribute__ ((__packed__));
} __attribute__ ((__gcc_struct__, __packed__));
#define arp_hrd ea_hdr.ar_hrd
#define arp_pro ea_hdr.ar_pro
#define arp_hln ea_hdr.ar_hln

View file

@ -285,6 +285,16 @@ bool event_loop(void) {
io->cb(io->data, IO_WRITE);
else if(FD_ISSET(io->fd, &readable))
io->cb(io->data, IO_READ);
else
continue;
/*
There are scenarios in which the callback will remove another io_t from the tree
(e.g. closing a double connection). Since splay_each does not support that, we
need to exit the loop now. That's okay, since any remaining events will get picked
up by the next select() call.
*/
break;
}
}
#else

View file

@ -1,23 +0,0 @@
/*
* fake library for ssh
*
* This file is included in getaddrinfo.c and getnameinfo.c.
* See getaddrinfo.c and getnameinfo.c.
*/
/* for old netdb.h */
#ifndef EAI_NODATA
#define EAI_NODATA 1
#endif
#ifndef EAI_MEMORY
#define EAI_MEMORY 2
#endif
#ifndef EAI_FAMILY
#define EAI_FAMILY 3
#endif
#ifndef EAI_SYSTEM
#define EAI_SYSTEM 4
#endif

View file

@ -1,102 +0,0 @@
/*
* fake library for ssh
*
* This file includes getaddrinfo(), freeaddrinfo() and gai_strerror().
* These funtions are defined in rfc2133.
*
* But these functions are not implemented correctly. The minimum subset
* is implemented for ssh use only. For exapmle, this routine assumes
* that ai_family is AF_INET. Don't use it for another purpose.
*/
#include "system.h"
#include "ipv4.h"
#include "ipv6.h"
#include "fake-getaddrinfo.h"
#include "xalloc.h"
#if !HAVE_DECL_GAI_STRERROR
char *gai_strerror(int ecode) {
switch (ecode) {
case EAI_NODATA:
return "No address associated with hostname";
case EAI_MEMORY:
return "Memory allocation failure";
case EAI_FAMILY:
return "Address family not supported";
default:
return "Unknown error";
}
}
#endif /* !HAVE_GAI_STRERROR */
#if !HAVE_DECL_FREEADDRINFO
void freeaddrinfo(struct addrinfo *ai) {
struct addrinfo *next;
while(ai) {
next = ai->ai_next;
free(ai);
ai = next;
}
}
#endif /* !HAVE_FREEADDRINFO */
#if !HAVE_DECL_GETADDRINFO
static struct addrinfo *malloc_ai(uint16_t port, uint32_t addr) {
struct addrinfo *ai;
ai = xzalloc(sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
ai->ai_addr = (struct sockaddr *)(ai + 1);
ai->ai_addrlen = sizeof(struct sockaddr_in);
ai->ai_addr->sa_family = ai->ai_family = AF_INET;
((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port;
((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr;
return ai;
}
int getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res) {
struct addrinfo *prev = NULL;
struct hostent *hp;
struct in_addr in = {0};
int i;
uint16_t port = 0;
if(hints && hints->ai_family != AF_INET && hints->ai_family != AF_UNSPEC)
return EAI_FAMILY;
if (servname)
port = htons(atoi(servname));
if (hints && hints->ai_flags & AI_PASSIVE) {
*res = malloc_ai(port, htonl(0x00000000));
return 0;
}
if (!hostname) {
*res = malloc_ai(port, htonl(0x7f000001));
return 0;
}
hp = gethostbyname(hostname);
if(!hp || !hp->h_addr_list || !hp->h_addr_list[0])
return EAI_NODATA;
for (i = 0; hp->h_addr_list[i]; i++) {
*res = malloc_ai(port, ((struct in_addr *)hp->h_addr_list[i])->s_addr);
if(prev)
prev->ai_next = *res;
prev = *res;
}
return 0;
}
#endif /* !HAVE_GETADDRINFO */

View file

@ -1,46 +0,0 @@
#ifndef _FAKE_GETADDRINFO_H
#define _FAKE_GETADDRINFO_H
#include "fake-gai-errnos.h"
#ifndef AI_PASSIVE
# define AI_PASSIVE 1
# define AI_CANONNAME 2
#endif
#ifndef NI_NUMERICHOST
# define NI_NUMERICHOST 2
# define NI_NAMEREQD 4
# define NI_NUMERICSERV 8
#endif
#ifndef AI_NUMERICHOST
#define AI_NUMERICHOST 4
#endif
#ifndef HAVE_STRUCT_ADDRINFO
struct addrinfo {
int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
int ai_family; /* PF_xxx */
int ai_socktype; /* SOCK_xxx */
int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
size_t ai_addrlen; /* length of ai_addr */
char *ai_canonname; /* canonical name for hostname */
struct sockaddr *ai_addr; /* binary address */
struct addrinfo *ai_next; /* next structure in linked list */
};
#endif /* !HAVE_STRUCT_ADDRINFO */
#if !HAVE_DECL_GETADDRINFO
int getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res);
#endif /* !HAVE_GETADDRINFO */
#if !HAVE_DECL_GAI_STRERROR
char *gai_strerror(int ecode);
#endif /* !HAVE_GAI_STRERROR */
#if !HAVE_DECL_FREEADDRINFO
void freeaddrinfo(struct addrinfo *ai);
#endif /* !HAVE_FREEADDRINFO */
#endif /* _FAKE_GETADDRINFO_H */

View file

@ -1,54 +0,0 @@
/*
* fake library for ssh
*
* This file includes getnameinfo().
* These funtions are defined in rfc2133.
*
* But these functions are not implemented correctly. The minimum subset
* is implemented for ssh use only. For exapmle, this routine assumes
* that ai_family is AF_INET. Don't use it for another purpose.
*/
#include "system.h"
#include "fake-getnameinfo.h"
#include "fake-getaddrinfo.h"
#if !HAVE_DECL_GETNAMEINFO
int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags) {
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
struct hostent *hp;
int len;
if(sa->sa_family != AF_INET)
return EAI_FAMILY;
if(serv && servlen) {
len = snprintf(serv, servlen, "%d", ntohs(sin->sin_port));
if(len < 0 || len >= servlen)
return EAI_MEMORY;
}
if(!host || !hostlen)
return 0;
if(flags & NI_NUMERICHOST) {
len = snprintf(host, hostlen, "%s", inet_ntoa(sin->sin_addr));
if(len < 0 || len >= hostlen)
return EAI_MEMORY;
return 0;
}
hp = gethostbyaddr((char *)&sin->sin_addr, sizeof(struct in_addr), AF_INET);
if(!hp || !hp->h_name || !hp->h_name[0])
return EAI_NODATA;
len = snprintf(host, hostlen, "%s", hp->h_name);
if(len < 0 || len >= hostlen)
return EAI_MEMORY;
return 0;
}
#endif /* !HAVE_GETNAMEINFO */

View file

@ -1,15 +0,0 @@
#ifndef _FAKE_GETNAMEINFO_H
#define _FAKE_GETNAMEINFO_H
#if !HAVE_DECL_GETNAMEINFO
int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags);
#endif /* !HAVE_GETNAMEINFO */
#ifndef NI_MAXSERV
# define NI_MAXSERV 32
#endif /* !NI_MAXSERV */
#ifndef NI_MAXHOST
# define NI_MAXHOST 1025
#endif /* !NI_MAXHOST */
#endif /* _FAKE_GETNAMEINFO_H */

498
src/fsck.c Normal file
View file

@ -0,0 +1,498 @@
/*
fsck.c -- Check the configuration files for problems
Copyright (C) 2014 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 "crypto.h"
#include "ecdsa.h"
#include "ecdsagen.h"
#include "fsck.h"
#include "names.h"
#ifndef DISABLE_LEGACY
#include "rsa.h"
#include "rsagen.h"
#endif
#include "tincctl.h"
#include "utils.h"
static bool ask_fix(void) {
if(force)
return true;
if(!tty)
return false;
again:
fprintf(stderr, "Fix y/n? ");
char buf[1024];
if(!fgets(buf, sizeof buf, stdin)) {
tty = false;
return false;
}
if(buf[0] == 'y' || buf[0] == 'Y')
return true;
if(buf[0] == 'n' || buf[0] == 'N')
return false;
goto again;
}
static void print_tinc_cmd(const char *argv0, const char *format, ...) {
if(confbasegiven)
fprintf(stderr, "%s -c %s ", argv0, confbase);
else if(netname)
fprintf(stderr, "%s -n %s ", argv0, netname);
else
fprintf(stderr, "%s ", argv0);
va_list va;
va_start(va, format);
vfprintf(stderr, format, va);
va_end(va);
fputc('\n', stderr);
}
static int strtailcmp(const char *str, const char *tail) {
size_t slen = strlen(str);
size_t tlen = strlen(tail);
if(tlen > slen)
return -1;
return memcmp(str + slen - tlen, tail, tlen);
}
static void check_conffile(const char *fname, bool server) {
FILE *f = fopen(fname, "r");
if(!f) {
fprintf(stderr, "ERROR: cannot read %s: %s\n", fname, strerror(errno));
return;
}
char line[2048];
int lineno = 0;
bool skip = false;
const int maxvariables = 50;
int count[maxvariables];
memset(count, 0, sizeof count);
while(fgets(line, sizeof line, f)) {
if(skip) {
if(!strncmp(line, "-----END", 8))
skip = false;
continue;
} else {
if(!strncmp(line, "-----BEGIN", 10)) {
skip = true;
continue;
}
}
int len;
char *variable, *value, *eol;
variable = value = line;
lineno++;
eol = line + strlen(line);
while(strchr("\t \r\n", *--eol))
*eol = '\0';
if(!line[0] || line[0] == '#')
continue;
len = strcspn(value, "\t =");
value += len;
value += strspn(value, "\t ");
if(*value == '=') {
value++;
value += strspn(value, "\t ");
}
variable[len] = '\0';
bool found = false;
for(int i = 0; variables[i].name; i++) {
if(strcasecmp(variables[i].name, variable))
continue;
found = true;
if(variables[i].type & VAR_OBSOLETE) {
fprintf(stderr, "WARNING: obsolete variable %s in %s line %d\n", variable, fname, lineno);
}
if(i < maxvariables)
count[i]++;
}
if(!found)
fprintf(stderr, "WARNING: unknown variable %s in %s line %d\n", variable, fname, lineno);
if(!*value)
fprintf(stderr, "ERROR: no value for variable %s in %s line %d\n", variable, fname, lineno);
}
for(int i = 0; variables[i].name && i < maxvariables; i++) {
if(count[i] > 1 && !(variables[i].type & VAR_MULTIPLE))
fprintf(stderr, "WARNING: multiple instances of variable %s in %s\n", variables[i].name, fname);
}
if(ferror(f))
fprintf(stderr, "ERROR: while reading %s: %s\n", fname, strerror(errno));
fclose(f);
}
int fsck(const char *argv0) {
#ifdef HAVE_MINGW
int uid = 0;
#else
uid_t uid = getuid();
#endif
// Check that tinc.conf is readable.
if(access(tinc_conf, R_OK)) {
fprintf(stderr, "ERROR: cannot read %s: %s\n", tinc_conf, strerror(errno));
if(errno == ENOENT) {
fprintf(stderr, "No tinc configuration found. Create a new one with:\n\n");
print_tinc_cmd(argv0, "init");
} else if(errno == EACCES) {
if(uid != 0)
fprintf(stderr, "You are currently not running tinc as root. Use sudo?\n");
else
fprintf(stderr, "Check the permissions of each component of the path %s.\n", tinc_conf);
}
return 1;
}
char *name = get_my_name(true);
if(!name) {
fprintf(stderr, "ERROR: tinc cannot run without a valid Name.\n");
return 1;
}
// Check for private keys.
// TODO: use RSAPrivateKeyFile and Ed25519PrivateKeyFile variables if present.
struct stat st;
char fname[PATH_MAX];
char dname[PATH_MAX];
#ifndef DISABLE_LEGACY
rsa_t *rsa_priv = NULL;
snprintf(fname, sizeof fname, "%s/rsa_key.priv", confbase);
if(stat(fname, &st)) {
if(errno != ENOENT) {
// Something is seriously wrong here. If we can access the directory with tinc.conf in it, we should certainly be able to stat() an existing file.
fprintf(stderr, "ERROR: cannot read %s: %s\n", fname, strerror(errno));
fprintf(stderr, "Please correct this error.\n");
return 1;
}
} else {
FILE *f = fopen(fname, "r");
if(!f) {
fprintf(stderr, "ERROR: could not open %s: %s\n", fname, strerror(errno));
return 1;
}
rsa_priv = rsa_read_pem_private_key(f);
fclose(f);
if(!rsa_priv) {
fprintf(stderr, "ERROR: No key or unusable key found in %s.\n", fname);
fprintf(stderr, "You can generate a new RSA key with:\n\n");
print_tinc_cmd(argv0, "generate-rsa-keys");
return 1;
}
#if !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN)
if(st.st_mode & 077) {
fprintf(stderr, "WARNING: unsafe file permissions on %s.\n", fname);
if(st.st_uid != uid) {
fprintf(stderr, "You are not running %s as the same uid as %s.\n", argv0, fname);
} else if(ask_fix()) {
if(chmod(fname, st.st_mode & ~077))
fprintf(stderr, "ERROR: could not change permissions of %s: %s\n", fname, strerror(errno));
else
fprintf(stderr, "Fixed permissions of %s.\n", fname);
}
}
#endif
}
#endif
ecdsa_t *ecdsa_priv = NULL;
snprintf(fname, sizeof fname, "%s/ed25519_key.priv", confbase);
if(stat(fname, &st)) {
if(errno != ENOENT) {
// Something is seriously wrong here. If we can access the directory with tinc.conf in it, we should certainly be able to stat() an existing file.
fprintf(stderr, "ERROR: cannot read %s: %s\n", fname, strerror(errno));
fprintf(stderr, "Please correct this error.\n");
return 1;
}
} else {
FILE *f = fopen(fname, "r");
if(!f) {
fprintf(stderr, "ERROR: could not open %s: %s\n", fname, strerror(errno));
return 1;
}
ecdsa_priv = ecdsa_read_pem_private_key(f);
fclose(f);
if(!ecdsa_priv) {
fprintf(stderr, "ERROR: No key or unusable key found in %s.\n", fname);
fprintf(stderr, "You can generate a new Ed25519 key with:\n\n");
print_tinc_cmd(argv0, "generate-ed25519-keys");
return 1;
}
#if !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN)
if(st.st_mode & 077) {
fprintf(stderr, "WARNING: unsafe file permissions on %s.\n", fname);
if(st.st_uid != uid) {
fprintf(stderr, "You are not running %s as the same uid as %s.\n", argv0, fname);
} else if(ask_fix()) {
if(chmod(fname, st.st_mode & ~077))
fprintf(stderr, "ERROR: could not change permissions of %s: %s\n", fname, strerror(errno));
else
fprintf(stderr, "Fixed permissions of %s.\n", fname);
}
}
#endif
}
#ifdef DISABLE_LEGACY
if(!ecdsa_priv) {
fprintf(stderr, "ERROR: No Ed25519 private key found.\n");
#else
if(!rsa_priv && !ecdsa_priv) {
fprintf(stderr, "ERROR: Neither RSA or Ed25519 private key found.\n");
#endif
fprintf(stderr, "You can generate new keys with:\n\n");
print_tinc_cmd(argv0, "generate-keys");
return 1;
}
// Check for public keys.
// TODO: use RSAPublicKeyFile variable if present.
snprintf(fname, sizeof fname, "%s/hosts/%s", confbase, name);
if(access(fname, R_OK))
fprintf(stderr, "WARNING: cannot read %s\n", fname);
FILE *f;
#ifndef DISABLE_LEGACY
rsa_t *rsa_pub = NULL;
f = fopen(fname, "r");
if(f)
rsa_pub = rsa_read_pem_public_key(f);
fclose(f);
if(rsa_priv) {
if(!rsa_pub) {
fprintf(stderr, "WARNING: No (usable) public RSA key found.\n");
if(ask_fix()) {
FILE *f = fopen(fname, "a");
if(f) {
if(rsa_write_pem_public_key(rsa_priv, f))
fprintf(stderr, "Wrote RSA public key to %s.\n", fname);
else
fprintf(stderr, "ERROR: could not write RSA public key to %s.\n", fname);
fclose(f);
} else {
fprintf(stderr, "ERROR: could not append to %s: %s\n", fname, strerror(errno));
}
}
} else {
// TODO: suggest remedies
size_t len = rsa_size(rsa_priv);
if(len != rsa_size(rsa_pub)) {
fprintf(stderr, "ERROR: public and private RSA keys do not match.\n");
return 1;
}
char buf1[len], buf2[len], buf3[len];
randomize(buf1, sizeof buf1);
buf1[0] &= 0x7f;
memset(buf2, 0, sizeof buf2);
memset(buf3, 0, sizeof buf2);
if(!rsa_public_encrypt(rsa_pub, buf1, sizeof buf1, buf2)) {
fprintf(stderr, "ERROR: public RSA key does not work.\n");
return 1;
}
if(!rsa_private_decrypt(rsa_priv, buf2, sizeof buf2, buf3)) {
fprintf(stderr, "ERROR: private RSA key does not work.\n");
return 1;
}
if(memcmp(buf1, buf3, sizeof buf1)) {
fprintf(stderr, "ERROR: public and private RSA keys do not match.\n");
return 1;
}
}
} else {
if(rsa_pub)
fprintf(stderr, "WARNING: A public RSA key was found but no private key is known.\n");
}
#endif
ecdsa_t *ecdsa_pub = NULL;
f = fopen(fname, "r");
if(f) {
ecdsa_pub = get_pubkey(f);
if(!f) {
rewind(f);
ecdsa_pub = ecdsa_read_pem_public_key(f);
}
}
fclose(f);
if(ecdsa_priv) {
if(!ecdsa_pub) {
fprintf(stderr, "WARNING: No (usable) public Ed25519 key found.\n");
if(ask_fix()) {
FILE *f = fopen(fname, "a");
if(f) {
if(ecdsa_write_pem_public_key(ecdsa_priv, f))
fprintf(stderr, "Wrote Ed25519 public key to %s.\n", fname);
else
fprintf(stderr, "ERROR: could not write Ed25519 public key to %s.\n", fname);
fclose(f);
} else {
fprintf(stderr, "ERROR: could not append to %s: %s\n", fname, strerror(errno));
}
}
} else {
// TODO: suggest remedies
char *key1 = ecdsa_get_base64_public_key(ecdsa_pub);
if(!key1) {
fprintf(stderr, "ERROR: public Ed25519 key does not work.\n");
return 1;
}
char *key2 = ecdsa_get_base64_public_key(ecdsa_priv);
if(!key2) {
free(key1);
fprintf(stderr, "ERROR: private Ed25519 key does not work.\n");
return 1;
}
int result = strcmp(key1, key2);
free(key1);
free(key2);
if(result) {
fprintf(stderr, "ERROR: public and private Ed25519 keys do not match.\n");
return 1;
}
}
} else {
if(ecdsa_pub)
fprintf(stderr, "WARNING: A public Ed25519 key was found but no private key is known.\n");
}
// Check whether scripts are executable
struct dirent *ent;
DIR *dir = opendir(confbase);
if(!dir) {
fprintf(stderr, "ERROR: cannot read directory %s: %s\n", confbase, strerror(errno));
return 1;
}
while((ent = readdir(dir))) {
if(strtailcmp(ent->d_name, "-up") && strtailcmp(ent->d_name, "-down"))
continue;
strncpy(fname, ent->d_name, sizeof fname);
char *dash = strrchr(fname, '-');
if(!dash)
continue;
*dash = 0;
if(strcmp(fname, "tinc") && strcmp(fname, "host") && strcmp(fname, "subnet")) {
static bool explained = false;
fprintf(stderr, "WARNING: Unknown script %s" SLASH "%s found.\n", confbase, ent->d_name);
if(!explained) {
fprintf(stderr, "The only scripts in %s executed by tinc are:\n", confbase);
fprintf(stderr, "tinc-up, tinc-down, host-up, host-down, subnet-up and subnet-down.\n");
explained = true;
}
continue;
}
snprintf(fname, sizeof fname, "%s" SLASH "%s", confbase, ent->d_name);
if(access(fname, R_OK | X_OK)) {
if(errno != EACCES) {
fprintf(stderr, "ERROR: cannot access %s: %s\n", fname, strerror(errno));
continue;
}
fprintf(stderr, "WARNING: cannot read and execute %s: %s\n", fname, strerror(errno));
if(ask_fix()) {
if(chmod(fname, 0755))
fprintf(stderr, "ERROR: cannot change permissions on %s: %s\n", fname, strerror(errno));
}
}
}
closedir(dir);
snprintf(dname, sizeof dname, "%s" SLASH "hosts", confbase);
dir = opendir(dname);
if(!dir) {
fprintf(stderr, "ERROR: cannot read directory %s: %s\n", dname, strerror(errno));
return 1;
}
while((ent = readdir(dir))) {
if(strtailcmp(ent->d_name, "-up") && strtailcmp(ent->d_name, "-down"))
continue;
strncpy(fname, ent->d_name, sizeof fname);
char *dash = strrchr(fname, '-');
if(!dash)
continue;
*dash = 0;
snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, ent->d_name);
if(access(fname, R_OK | X_OK)) {
if(errno != EACCES) {
fprintf(stderr, "ERROR: cannot access %s: %s\n", fname, strerror(errno));
continue;
}
fprintf(stderr, "WARNING: cannot read and execute %s: %s\n", fname, strerror(errno));
if(ask_fix()) {
if(chmod(fname, 0755))
fprintf(stderr, "ERROR: cannot change permissions on %s: %s\n", fname, strerror(errno));
}
}
}
closedir(dir);
// Check for obsolete / unsafe / unknown configuration variables.
check_conffile(tinc_conf, true);
dir = opendir(dname);
if(dir) {
while((ent = readdir(dir))) {
if(!check_id(ent->d_name))
continue;
snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, ent->d_name);
check_conffile(fname, false);
}
closedir(dir);
}
return 0;
}

View file

@ -1,6 +1,6 @@
/*
ecdh.c -- Diffie-Hellman key exchange handling
Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org>
fsck.h -- header for fsck.c.
Copyright (C) 2012 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
@ -17,21 +17,10 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "../system.h"
#ifndef __TINC_FSCK_H__
#define __TINC_FSCK_H__
#include "../ecdh.h"
#include "../logger.h"
#include "../utils.h"
#include "../xalloc.h"
extern int fsck(const char *argv0);
ecdh_t *ecdh_generate_public(void *pubkey) {
logger(DEBUG_ALWAYS, LOG_ERR, "EC support using libgcrypt not implemented");
return NULL;
}
#endif
bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) {
return false
}
void ecdh_free(ecdh_t *ecdh) {
}

View file

@ -1,67 +0,0 @@
/*
ecdsa.c -- ECDSA key handling
Copyright (C) 2011-2013 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 "../logger.h"
#include "../ecdsa.h"
#include "../utils.h"
#include "../xalloc.h"
// Get and set ECDSA keys
//
ecdsa_t *ecdsa_set_base64_public_key(const char *p) {
logger(DEBUG_ALWAYS, LOG_ERR, "EC support using libgcrypt not implemented");
return NULL;
}
char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) {
return NULL;
}
// Read PEM ECDSA keys
ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) {
logger(DEBUG_ALWAYS, LOG_ERR, "EC support using libgcrypt not implemented");
return NULL;
}
ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) {
logger(DEBUG_ALWAYS, LOG_ERR, "EC support using libgcrypt not implemented");
return NULL;
}
size_t ecdsa_size(ecdsa_t *ecdsa) {
return 0;
}
bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t len, void *sig) {
return false;
}
bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t len, const void *sig) {
return false;
}
bool ecdsa_active(ecdsa_t *ecdsa) {
return false;
}
void ecdsa_free(ecdsa_t *ecdsa) {
}

View file

@ -19,11 +19,88 @@
#include "../system.h"
#include "digest.h"
#include "../digest.h"
#include "../prf.h"
#include "../ed25519/sha512.h"
static void memxor(char *buf, char c, size_t len) {
for(size_t i = 0; i < len; i++)
buf[i] ^= c;
}
static const size_t mdlen = 64;
static const size_t blklen = 128;
static bool hmac_sha512(const char *key, size_t keylen, const char *msg, size_t msglen, char *out) {
char tmp[blklen + mdlen];
sha512_context md;
if(keylen <= blklen) {
memcpy(tmp, key, keylen);
memset(tmp + keylen, 0, blklen - keylen);
} else {
if(sha512(key, keylen, tmp) != 0)
return false;
memset(tmp + mdlen, 0, blklen - mdlen);
}
if(sha512_init(&md) != 0)
return false;
// ipad
memxor(tmp, 0x36, blklen);
if(sha512_update(&md, tmp, blklen) != 0)
return false;
// message
if(sha512_update(&md, msg, msglen) != 0)
return false;
if(sha512_final(&md, tmp + blklen) != 0)
return false;
// opad
memxor(tmp, 0x36 ^ 0x5c, blklen);
if(sha512(tmp, sizeof tmp, out) != 0)
return false;
return true;
}
/* Generate key material from a master secret and a seed, based on RFC 4346 section 5.
We use SHA512 instead of MD5 and SHA1.
*/
bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen) {
logger(DEBUG_ALWAYS, LOG_ERR, "PRF support using libgcrypt not implemented");
/* Data is what the "inner" HMAC function processes.
It consists of the previous HMAC result plus the seed.
*/
char data[mdlen + seedlen];
memset(data, 0, mdlen);
memcpy(data + mdlen, seed, seedlen);
char hash[mdlen];
while(outlen > 0) {
/* Inner HMAC */
if(!hmac_sha512(secret, secretlen, data, sizeof data, data))
return false;
/* Outer HMAC */
if(outlen >= mdlen) {
if(!hmac_sha512(secret, secretlen, data, sizeof data, out))
return false;
out += mdlen;
outlen -= mdlen;
} else {
if(!hmac_sha512(secret, secretlen, data, sizeof data, hash))
return false;
memcpy(out, hash, outlen);
out += outlen;
outlen = 0;
}
}
return true;
}

View file

@ -149,7 +149,7 @@ static void sssp_bfs(void) {
abort();
for splay_each(edge_t, e, n->edge_tree) { /* "e" is the edge connected to "from" */
if(!e->reverse)
if(!e->reverse || e->to == myself)
continue;
/* Situation:
@ -238,10 +238,11 @@ static void check_reachability(void) {
n->status.udp_confirmed = false;
n->maxmtu = MTU;
n->maxrecentlen = 0;
n->minmtu = 0;
n->mtuprobes = 0;
timeout_del(&n->mtutimeout);
timeout_del(&n->udp_ping_timeout);
char *name;
char *address;
@ -275,6 +276,10 @@ static void check_reachability(void) {
update_node_udp(n, NULL);
memset(&n->status, 0, sizeof n->status);
n->options = 0;
} else if(n->connection) {
// Speed up UDP probing by sending our key.
if(!n->status.sptps)
send_ans_key(n);
}
}

View file

@ -29,7 +29,7 @@ static uint32_t hash_function(const void *p, size_t len) {
uint32_t hash = 0;
while(true) {
for(int i = len > 4 ? 4 : len; --i;)
hash += q[len - i] << (8 * i);
hash += (uint32_t)q[len - i] << (8 * i);
hash *= 0x9e370001UL; // Golden ratio prime.
if(len <= 4)
break;

View file

@ -1,7 +1,7 @@
/*
have.h -- include headers which are known to exist
Copyright (C) 1998-2005 Ivo Timmermans
2003-2013 Guus Sliepen <guus@tinc-vpn.org>
2003-2016 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -22,17 +22,14 @@
#define __TINC_HAVE_H__
#ifdef HAVE_MINGW
#ifdef WITH_WINDOWS2000
#define WINVER Windows2000
#else
#define WINVER WindowsXP
#endif
#define WIN32_LEAN_AND_MEAN
#endif
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>
#include <signal.h>
@ -40,6 +37,8 @@
#include <fcntl.h>
#include <unistd.h>
#include <limits.h>
#include <math.h>
#include <time.h>
#ifdef HAVE_MINGW
#include <w32api.h>
@ -48,10 +47,6 @@
#include <ws2tcpip.h>
#endif
#ifdef HAVE_STDBOOL_H
#include <stdbool.h>
#endif
#ifdef HAVE_TERMIOS_H
#include <termios.h>
#endif
@ -70,9 +65,6 @@
#include <sys/time.h>
#endif
#ifdef HAVE_TIME_H
#include <time.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
@ -102,10 +94,6 @@
#include <sys/resource.h>
#endif
#ifdef HAVE_SYS_UIO_H
#include <sys/uio.h>
#endif
#ifdef HAVE_SYS_UN_H
#include <sys/un.h>
#endif
@ -197,6 +185,28 @@
#include <netinet/if_ether.h>
#endif
#ifdef HAVE_ARPA_NAMESER_H
#include <arpa/nameser.h>
#endif
#ifdef HAVE_RESOLV_H
#include <resolv.h>
#endif
#ifdef HAVE_LINUX_IF_TUN_H
#include <linux/if_tun.h>
#endif
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#else
#include "getopt.h"
#endif
#ifdef STATUS
#undef STATUS
#endif
#ifdef HAVE_MINGW
#define SLASH "\\"
#else

198
src/ifconfig.c Normal file
View file

@ -0,0 +1,198 @@
/*
ifconfig.c -- Generate platform specific interface configuration commands
Copyright (C) 2016 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "system.h"
#include "conf.h"
#include "ifconfig.h"
#include "subnet.h"
static long start;
#ifndef HAVE_MINGW
void ifconfig_header(FILE *out) {
fprintf(out, "#!/bin/sh\n");
start = ftell(out);
}
void ifconfig_dhcp(FILE *out) {
fprintf(out, "dhclient -nw \"$INTERFACE\"\n");
}
void ifconfig_dhcp6(FILE *out) {
fprintf(out, "dhclient -6 -nw \"$INTERFACE\"\n");
}
void ifconfig_slaac(FILE *out) {
#ifdef HAVE_LINUX
fprintf(out, "echo 1 >\"/proc/sys/net/ipv6/conf/$INTERFACE/accept_ra\"\n");
fprintf(out, "echo 1 >\"/proc/sys/net/ipv6/conf/$INTERFACE/autoconf\"\n");
#else
fprintf(out, "rtsol \"$INTERFACE\" &\n");
#endif
}
bool ifconfig_footer(FILE *out) {
if(ftell(out) == start) {
fprintf(out, "echo 'Unconfigured tinc-up script, please edit '$0'!'\n\n#ifconfig $INTERFACE <your vpn IP address> netmask <netmask of whole VPN>\n");
return false;
} else {
#ifdef HAVE_LINUX
fprintf(out, "ip link set \"$INTERFACE\" up\n");
#else
fprintf(out, "ifconfig \"$INTERFACE\" up\n");
#endif
return true;
}
}
#else
void ifconfig_header(FILE *out) {
start = ftell(out);
}
void ifconfig_dhcp(FILE *out) {
fprintf(out, "netsh interface ipv4 set address \"%%INTERFACE%%\" dhcp\n");
}
void ifconfig_dhcp6(FILE *out) {
fprintf(stderr, "DHCPv6 requested, but not supported by tinc on this platform\n");
}
void ifconfig_slaac(FILE *out) {
// It's the default?
}
bool ifconfig_footer(FILE *out) {
return ftell(out) != start;
}
#endif
static subnet_t ipv4, ipv6;
void ifconfig_address(FILE *out, const char *value) {
subnet_t address = {};
char address_str[MAXNETSTR];
if(!str2net(&address, value) || !net2str(address_str, sizeof address_str, &address)) {
fprintf(stderr, "Could not parse address in Ifconfig statement\n");
return;
}
switch(address.type) {
case SUBNET_IPV4: ipv4 = address; break;
case SUBNET_IPV6: ipv6 = address; break;
default: return;
}
#if defined(HAVE_LINUX)
switch(address.type) {
case SUBNET_MAC: fprintf(out, "ip link set \"$INTERFACE\" address %s\n", address_str); break;
case SUBNET_IPV4: fprintf(out, "ip addr replace %s dev \"$INTERFACE\"\n", address_str); break;
case SUBNET_IPV6: fprintf(out, "ip addr replace %s dev \"$INTERFACE\"\n", address_str); break;
default: return;
}
#elif defined(HAVE_BSD)
switch(address.type) {
case SUBNET_MAC: fprintf(out, "ifconfig \"$INTERFACE\" link %s\n", address_str); break;
case SUBNET_IPV4: fprintf(out, "ifconfig \"$INTERFACE\" %s\n", address_str); break;
case SUBNET_IPV6: fprintf(out, "ifconfig \"$INTERFACE\" inet6 %s\n", address_str); break;
default: return;
}
#elif defined(HAVE_MINGW) || defined(HAVE_CYGWIN)
switch(address.type) {
case SUBNET_MAC: fprintf(out, "ip link set \"$INTERFACE\" address %s\n", address_str); break;
case SUBNET_IPV4: fprintf(out, "netsh inetface ipv4 set address \"$INTERFACE\" static %s\n", address_str); break;
case SUBNET_IPV6: fprintf(out, "netsh inetface ipv6 set address \"$INTERFACE\" static %s\n", address_str); break;
default: return;
}
#endif
}
void ifconfig_route(FILE *out, const char *value) {
subnet_t subnet = {}, gateway = {};
char subnet_str[MAXNETSTR] = "", gateway_str[MAXNETSTR] = "";
char *sep = strchr(value, ' ');
if(sep)
*sep++ = 0;
if(!str2net(&subnet, value) || !net2str(subnet_str, sizeof subnet_str, &subnet) || subnet.type == SUBNET_MAC) {
fprintf(stderr, "Could not parse subnet in Route statement\n");
return;
}
if(sep) {
if(!str2net(&gateway, sep) || !net2str(gateway_str, sizeof gateway_str, &gateway) || gateway.type != subnet.type) {
fprintf(stderr, "Could not parse gateway in Route statement\n");
return;
}
char *slash = strchr(gateway_str, '/'); if(slash) *slash = 0;
}
#if defined(HAVE_LINUX)
if(*gateway_str) {
switch(subnet.type) {
case SUBNET_IPV4: fprintf(out, "ip route add %s via %s dev \"$INTERFACE\"\n", subnet_str, gateway_str); break;
case SUBNET_IPV6: fprintf(out, "ip route add %s via %s dev \"$INTERFACE\"\n", subnet_str, gateway_str); break;
default: return;
}
} else {
switch(subnet.type) {
case SUBNET_IPV4: fprintf(out, "ip route add %s dev \"$INTERFACE\"\n", subnet_str); break;
case SUBNET_IPV6: fprintf(out, "ip route add %s dev \"$INTERFACE\"\n", subnet_str); break;
default: return;
}
}
#elif defined(HAVE_BSD)
// BSD route command is silly and doesn't accept an interface name as a destination.
if(!*gateway_str) {
switch(subnet.type) {
case SUBNET_IPV4:
if(!ipv4.type) {
fprintf(stderr, "Route requested but no Ifconfig\n");
return;
}
net2str(gateway_str, sizeof gateway_str, &ipv4);
break;
case SUBNET_IPV6:
if(!ipv6.type) {
fprintf(stderr, "Route requested but no Ifconfig\n");
return;
}
net2str(gateway_str, sizeof gateway_str, &ipv6);
break;
default: return;
}
char *slash = strchr(gateway_str, '/'); if(slash) *slash = 0;
}
switch(subnet.type) {
case SUBNET_IPV4: fprintf(out, "route add %s %s\n", subnet_str, gateway_str); break;
case SUBNET_IPV6: fprintf(out, "route add -inet6 %s %s\n", subnet_str, gateway_str); break;
default: return;
}
#elif defined(HAVE_MINGW) || defined(HAVE_CYGWIN)
if(*gateway_str) {
switch(subnet.type) {
case SUBNET_IPV4: fprintf(out, "netsh inetface ipv4 add route %s \"%%INTERFACE%%\" %s\n", subnet_str, gateway_str); break;
case SUBNET_IPV6: fprintf(out, "netsh inetface ipv6 add route %s \"%%INTERFACE%%\" %s\n", subnet_str, gateway_str); break;
default: return;
}
} else {
switch(subnet.type) {
case SUBNET_IPV4: fprintf(out, "netsh inetface ipv4 add route %s \"%%INTERFACE%%\"\n", subnet_str); break;
case SUBNET_IPV6: fprintf(out, "netsh inetface ipv6 add route %s \"%%INTERFACE%%\"\n", subnet_str); break;
default: return;
}
}
#endif
}

31
src/ifconfig.h Normal file
View file

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

View file

@ -1,6 +1,6 @@
/*
invitation.c -- Create and accept invitations
Copyright (C) 2013-2014 Guus Sliepen <guus@tinc-vpn.org>
Copyright (C) 2013-2015 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
@ -23,16 +23,20 @@
#include "crypto.h"
#include "ecdsa.h"
#include "ecdsagen.h"
#include "ifconfig.h"
#include "invitation.h"
#include "names.h"
#include "netutl.h"
#include "rsagen.h"
#include "script.h"
#include "sptps.h"
#include "subnet.h"
#include "tincctl.h"
#include "utils.h"
#include "xalloc.h"
#include "ed25519/sha512.h"
int addressfamily = AF_UNSPEC;
static void scan_for_hostname(const char *filename, char **hostname, char **port) {
@ -82,11 +86,11 @@ char *get_my_hostname() {
char *port = NULL;
char *hostport = NULL;
char *name = get_my_name(false);
char *filename = NULL;
char filename[PATH_MAX] = {0};
// Use first Address statement in own host config file
if(check_id(name)) {
xasprintf(&filename, "%s" SLASH "hosts" SLASH "%s", confbase, name);
snprintf(filename, sizeof filename, "%s" SLASH "hosts" SLASH "%s", confbase, name);
scan_for_hostname(filename, &hostname, &port);
scan_for_hostname(tinc_conf, &hostname, &port);
}
@ -180,7 +184,7 @@ again:
hostname = xstrdup(line);
save:
if(filename) {
if(*filename) {
FILE *f = fopen(filename, "a");
if(f) {
fprintf(f, "\nAddress = %s\n", hostname);
@ -205,7 +209,6 @@ done:
free(hostname);
free(port);
free(filename);
return hostport;
}
@ -241,14 +244,12 @@ int cmd_invite(int argc, char *argv[]) {
return 1;
// Ensure no host configuration file with that name exists
char *filename = NULL;
xasprintf(&filename, "%s" SLASH "hosts" SLASH "%s", confbase, argv[1]);
char filename[PATH_MAX];
snprintf(filename, sizeof filename, "%s" SLASH "hosts" SLASH "%s", confbase, argv[1]);
if(!access(filename, F_OK)) {
free(filename);
fprintf(stderr, "A host config file for %s already exists!\n", argv[1]);
return 1;
}
free(filename);
// If a daemon is running, ensure no other nodes know about this name
bool found = false;
@ -270,12 +271,9 @@ int cmd_invite(int argc, char *argv[]) {
}
}
char hash[25];
xasprintf(&filename, "%s" SLASH "invitations", confbase);
snprintf(filename, sizeof filename, "%s" SLASH "invitations", confbase);
if(mkdir(filename, 0700) && errno != EEXIST) {
fprintf(stderr, "Could not create directory %s: %s\n", filename, strerror(errno));
free(filename);
return 1;
}
@ -283,7 +281,6 @@ int cmd_invite(int argc, char *argv[]) {
DIR *dir = opendir(filename);
if(!dir) {
fprintf(stderr, "Could not read directory %s: %s\n", filename, strerror(errno));
free(filename);
return 1;
}
@ -295,9 +292,9 @@ int cmd_invite(int argc, char *argv[]) {
while((ent = readdir(dir))) {
if(strlen(ent->d_name) != 24)
continue;
char *invname;
char invname[PATH_MAX];
struct stat st;
xasprintf(&invname, "%s" SLASH "%s", filename, ent->d_name);
snprintf(invname, sizeof invname, "%s" SLASH "%s", filename, ent->d_name);
if(!stat(invname, &st)) {
if(deadline < st.st_mtime)
count++;
@ -307,21 +304,17 @@ int cmd_invite(int argc, char *argv[]) {
fprintf(stderr, "Could not stat %s: %s\n", invname, strerror(errno));
errno = 0;
}
free(invname);
}
closedir(dir);
if(errno) {
fprintf(stderr, "Error while reading directory %s: %s\n", filename, strerror(errno));
closedir(dir);
free(filename);
return 1;
}
closedir(dir);
free(filename);
ecdsa_t *key;
xasprintf(&filename, "%s" SLASH "invitations" SLASH "ed25519_key.priv", confbase);
snprintf(filename, sizeof filename, "%s" SLASH "invitations" SLASH "ed25519_key.priv", confbase);
// Remove the key if there are no outstanding invitations.
if(!count)
@ -332,23 +325,23 @@ int cmd_invite(int argc, char *argv[]) {
if(!f) {
if(errno != ENOENT) {
fprintf(stderr, "Could not read %s: %s\n", filename, strerror(errno));
free(filename);
return 1;
}
key = ecdsa_generate();
if(!key) {
free(filename);
if(!key)
return 1;
}
f = fopen(filename, "w");
if(!f) {
fprintf(stderr, "Could not write %s: %s\n", filename, strerror(errno));
free(filename);
return 1;
}
chmod(filename, 0600);
ecdsa_write_pem_private_key(key, f);
if(!ecdsa_write_pem_private_key(key, f)) {
fprintf(stderr, "Could not write ECDSA private key\n");
fclose(f);
return 1;
}
fclose(f);
if(connect_tincd(false))
@ -360,16 +353,13 @@ int cmd_invite(int argc, char *argv[]) {
fprintf(stderr, "Could not read private key from %s\n", filename);
}
free(filename);
if(!key)
return 1;
// Create a hash of the key.
char hash[64];
char *fingerprint = ecdsa_get_base64_public_key(key);
digest_t *digest = digest_open_by_name("sha256", 18);
if(!digest)
abort();
digest_create(digest, fingerprint, strlen(fingerprint), hash);
sha512(fingerprint, strlen(fingerprint), hash);
b64encode_urlsafe(hash, hash, 18);
// Create a random cookie for this invitation.
@ -378,20 +368,19 @@ int cmd_invite(int argc, char *argv[]) {
// Create a filename that doesn't reveal the cookie itself
char buf[18 + strlen(fingerprint)];
char cookiehash[25];
char cookiehash[64];
memcpy(buf, cookie, 18);
memcpy(buf + 18, fingerprint, sizeof buf - 18);
digest_create(digest, buf, sizeof buf, cookiehash);
sha512(buf, sizeof buf, cookiehash);
b64encode_urlsafe(cookiehash, cookiehash, 18);
b64encode_urlsafe(cookie, cookie, 18);
// Create a file containing the details of the invitation.
xasprintf(&filename, "%s" SLASH "invitations" SLASH "%s", confbase, cookiehash);
snprintf(filename, sizeof filename, "%s" SLASH "invitations" SLASH "%s", confbase, cookiehash);
int ifd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
if(!ifd) {
fprintf(stderr, "Could not create invitation file %s: %s\n", filename, strerror(errno));
free(filename);
return 1;
}
f = fdopen(ifd, "w");
@ -403,7 +392,7 @@ int cmd_invite(int argc, char *argv[]) {
// Fill in the details.
fprintf(f, "Name = %s\n", argv[1]);
if(netname)
if(check_netname(netname, true))
fprintf(f, "NetName = %s\n", netname);
fprintf(f, "ConnectTo = %s\n", myname);
@ -426,11 +415,10 @@ int cmd_invite(int argc, char *argv[]) {
fprintf(f, "#---------------------------------------------------------------#\n");
fprintf(f, "Name = %s\n", myname);
char *filename2;
xasprintf(&filename2, "%s" SLASH "hosts" SLASH "%s", confbase, myname);
char filename2[PATH_MAX];
snprintf(filename2, sizeof filename2, "%s" SLASH "hosts" SLASH "%s", confbase, myname);
fcopy(f, filename2);
fclose(f);
free(filename2);
// Create an URL from the local address, key hash and cookie
char *url;
@ -449,7 +437,6 @@ int cmd_invite(int argc, char *argv[]) {
puts(url);
free(url);
free(filename);
free(address);
return 0;
@ -554,12 +541,17 @@ static bool finalize_join(void) {
}
if(!check_id(name)) {
fprintf(stderr, "Invalid Name found in invitation: %s!\n", name);
fprintf(stderr, "Invalid Name found in invitation!\n");
return false;
}
if(!netname)
if(!netname) {
netname = grep(data, "NetName");
if(netname && !check_netname(netname, true)) {
fprintf(stderr, "Unsafe NetName found in invitation!\n");
return false;
}
}
bool ask_netname = false;
char temp_netname[32];
@ -570,7 +562,7 @@ make_names:
confbase = NULL;
}
make_names();
make_names(false);
free(tinc_conf);
free(hosts_dir);
@ -608,8 +600,8 @@ make_names:
fprintf(f, "Name = %s\n", name);
char *filename;
xasprintf(&filename, "%s" SLASH "%s", hosts_dir, name);
char filename[PATH_MAX];
snprintf(filename, sizeof filename, "%s" SLASH "%s", hosts_dir, name);
FILE *fh = fopen(filename, "w");
if(!fh) {
fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno));
@ -617,7 +609,19 @@ make_names:
return false;
}
snprintf(filename, sizeof filename, "%s" SLASH "tinc-up.invitation", confbase);
FILE *fup = fopen(filename, "w");
if(!fup) {
fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno));
fclose(f);
fclose(fh);
return false;
}
ifconfig_header(fup);
// Filter first chunk on approved keywords, split between tinc.conf and hosts/Name
// Generate a tinc-up script from Ifconfig and Route keywords.
// Other chunks go unfiltered to their respective host config files
const char *p = data;
char *l, *value;
@ -656,6 +660,24 @@ make_names:
break;
}
// Handle Ifconfig and Route statements
if(!found) {
if(!strcasecmp(l, "Ifconfig")) {
if(!strcasecmp(value, "dhcp"))
ifconfig_dhcp(fup);
else if(!strcasecmp(value, "dhcp6"))
ifconfig_dhcp6(fup);
else if(!strcasecmp(value, "slaac"))
ifconfig_slaac(fup);
else
ifconfig_address(fup, value);
continue;
} else if(!strcasecmp(l, "Route")) {
ifconfig_route(fup, value);
continue;
}
}
// Ignore unknown and unsafe variables
if(!found) {
fprintf(stderr, "Ignoring unknown variable '%s' in invitation.\n", l);
@ -670,7 +692,8 @@ make_names:
}
fclose(f);
free(filename);
bool valid_tinc_up = ifconfig_footer(fup);
fclose(fup);
while(l && !strcasecmp(l, "Name")) {
if(!check_id(value)) {
@ -683,7 +706,7 @@ make_names:
return false;
}
xasprintf(&filename, "%s" SLASH "%s", hosts_dir, value);
snprintf(filename, sizeof filename, "%s" SLASH "%s", hosts_dir, value);
f = fopen(filename, "w");
if(!f) {
@ -711,7 +734,6 @@ make_names:
}
fclose(f);
free(filename);
}
// Generate our key and send a copy to the server
@ -723,8 +745,10 @@ make_names:
if(!b64key)
return false;
xasprintf(&filename, "%s" SLASH "ed25519_key.priv", confbase);
snprintf(filename, sizeof filename, "%s" SLASH "ed25519_key.priv", confbase);
f = fopenmask(filename, "w", 0600);
if(!f)
return false;
if(!ecdsa_write_pem_private_key(key, f)) {
fprintf(stderr, "Error writing private key!\n");
@ -739,20 +763,25 @@ make_names:
sptps_send_record(&sptps, 1, b64key, strlen(b64key));
free(b64key);
ecdsa_free(key);
#ifndef DISABLE_LEGACY
rsa_t *rsa = rsa_generate(2048, 0x1001);
xasprintf(&filename, "%s" SLASH "rsa_key.priv", confbase);
snprintf(filename, sizeof filename, "%s" SLASH "rsa_key.priv", confbase);
f = fopenmask(filename, "w", 0600);
rsa_write_pem_private_key(rsa, f);
if(!f || !rsa_write_pem_private_key(rsa, f)) {
fprintf(stderr, "Could not write private RSA key\n");
} else if(!rsa_write_pem_public_key(rsa, fh)) {
fprintf(stderr, "Could not write public RSA key\n");
}
fclose(f);
rsa_write_pem_public_key(rsa, fh);
fclose(fh);
ecdsa_free(key);
rsa_free(rsa);
#endif
check_port(name);
@ -768,17 +797,69 @@ ask_netname:
line[strlen(line) - 1] = 0;
char *newbase;
xasprintf(&newbase, CONFDIR SLASH "tinc" SLASH "%s", line);
char newbase[PATH_MAX];
snprintf(newbase, sizeof newbase, CONFDIR SLASH "tinc" SLASH "%s", line);
if(rename(confbase, newbase)) {
fprintf(stderr, "Error trying to rename %s to %s: %s\n", confbase, newbase, strerror(errno));
free(newbase);
goto ask_netname;
}
free(newbase);
netname = line;
make_names();
make_names(false);
}
char filename2[PATH_MAX];
snprintf(filename, sizeof filename, "%s" SLASH "tinc-up.invitation", confbase);
snprintf(filename2, sizeof filename2, "%s" SLASH "tinc-up", confbase);
if(valid_tinc_up) {
if(tty) {
FILE *fup = fopen(filename, "r");
if(fup) {
fprintf(stderr, "\nPlease review the following tinc-up script:\n\n");
char buf[MAXSIZE];
while(fgets(buf, sizeof buf, fup))
fputs(buf, stderr);
fclose(fup);
int response = 0;
do {
fprintf(stderr, "\nDo you want to use this script [y]es/[n]o/[e]dit? ");
response = tolower(getchar());
} while(!strchr("yne", response));
fprintf(stderr, "\n");
if(response == 'e') {
char *command;
#ifndef HAVE_MINGW
xasprintf(&command, "\"%s\" \"%s\"", getenv("VISUAL") ?: getenv("EDITOR") ?: "vi", filename);
#else
xasprintf(&command, "edit \"%s\"", filename);
#endif
if(system(command))
response = 'n';
else
response = 'y';
free(command);
}
if(response == 'y') {
rename(filename, filename2);
chmod(filename2, 0755);
fprintf(stderr, "tinc-up enabled.\n");
} else {
fprintf(stderr, "tinc-up has been left disabled.\n");
}
}
} else {
fprintf(stderr, "A tinc-up script was generated, but has been left disabled.\n");
}
} else {
// A placeholder was generated.
rename(filename, filename2);
chmod(filename2, 0755);
}
fprintf(stderr, "Configuration stored in: %s\n", confbase);
@ -922,16 +1003,31 @@ int cmd_join(int argc, char *argv[]) {
if(!ai)
return 1;
sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if(sock <= 0) {
fprintf(stderr, "Could not open socket: %s\n", strerror(errno));
struct addrinfo *aip = NULL;
next:
if(!aip)
aip = ai;
else {
aip = aip->ai_next;
if(!aip)
return 1;
}
if(connect(sock, ai->ai_addr, ai->ai_addrlen)) {
fprintf(stderr, "Could not connect to %s port %s: %s\n", address, port, strerror(errno));
sock = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol);
if(sock <= 0) {
fprintf(stderr, "Could not open socket: %s\n", strerror(errno));
goto next;
}
if(connect(sock, aip->ai_addr, aip->ai_addrlen)) {
char *addrstr, *portstr;
sockaddr2str((sockaddr_t *)aip->ai_addr, &addrstr, &portstr);
fprintf(stderr, "Could not connect to %s port %s: %s\n", addrstr, portstr, strerror(errno));
free(addrstr);
free(portstr);
closesocket(sock);
return 1;
goto next;
}
fprintf(stderr, "Connected to %s port %s...\n", address, port);
@ -944,7 +1040,7 @@ int cmd_join(int argc, char *argv[]) {
if(!sendline(sock, "0 ?%s %d.%d", b64key, PROT_MAJOR, 1)) {
fprintf(stderr, "Error sending request to %s port %s: %s\n", address, port, strerror(errno));
closesocket(sock);
return 1;
goto next;
}
char hisname[4096] = "";
@ -953,16 +1049,13 @@ int cmd_join(int argc, char *argv[]) {
if(!recvline(sock, line, sizeof line) || sscanf(line, "%d %s %d.%d", &code, hisname, &hismajor, &hisminor) < 3 || code != 0 || hismajor != PROT_MAJOR || !check_id(hisname) || !recvline(sock, line, sizeof line) || !rstrip(line) || sscanf(line, "%d ", &code) != 1 || code != ACK || strlen(line) < 3) {
fprintf(stderr, "Cannot read greeting from peer\n");
closesocket(sock);
return 1;
goto next;
}
// Check if the hash of the key he gave us matches the hash in the URL.
char *fingerprint = line + 2;
digest_t *digest = digest_open_by_name("sha256", 18);
if(!digest)
abort();
char hishash[18];
if(!digest_create(digest, fingerprint, strlen(fingerprint), hishash)) {
char hishash[64];
if(sha512(fingerprint, strlen(fingerprint), hishash)) {
fprintf(stderr, "Could not create digest\n%s\n", line + 2);
return 1;
}
@ -992,8 +1085,14 @@ int cmd_join(int argc, char *argv[]) {
return 1;
}
if(!sptps_receive_data(&sptps, line, len))
char *p = line;
while(len) {
int done = sptps_receive_data(&sptps, p, len);
if(!done)
return 1;
len -= done;
p += done;
}
}
sptps_stop(&sptps);

View file

@ -81,7 +81,7 @@ struct ip {
uint8_t ip_p;
uint16_t ip_sum;
struct in_addr ip_src, ip_dst;
} __attribute__ ((__packed__));
} __attribute__ ((__gcc_struct__, __packed__));
#endif
#ifndef IP_OFFMASK
@ -143,7 +143,7 @@ struct icmp {
#define icmp_radv icmp_dun.id_radv
#define icmp_mask icmp_dun.id_mask
#define icmp_data icmp_dun.id_data
} __attribute__ ((__packed__));
} __attribute__ ((__gcc_struct__, __packed__));
#endif
#endif /* __TINC_IPV4_H__ */

View file

@ -1,7 +1,7 @@
/*
ipv6.h -- missing IPv6 related definitions
Copyright (C) 2005 Ivo Timmermans
2006-2012 Guus Sliepen <guus@tinc-vpn.org>
2006-2016 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -29,29 +29,6 @@
#define IPPROTO_ICMPV6 58
#endif
#ifndef HAVE_STRUCT_IN6_ADDR
struct in6_addr {
union {
uint8_t u6_addr8[16];
uint16_t u6_addr16[8];
uint32_t u6_addr32[4];
} in6_u;
} __attribute__ ((__packed__));
#define s6_addr in6_u.u6_addr8
#define s6_addr16 in6_u.u6_addr16
#define s6_addr32 in6_u.u6_addr32
#endif
#ifndef HAVE_STRUCT_SOCKADDR_IN6
struct sockaddr_in6 {
uint16_t sin6_family;
uint16_t sin6_port;
uint32_t sin6_flowinfo;
struct in6_addr sin6_addr;
uint32_t sin6_scope_id;
} __attribute__ ((__packed__));
#endif
#ifndef IN6_IS_ADDR_V4MAPPED
#define IN6_IS_ADDR_V4MAPPED(a) \
((((__const uint32_t *) (a))[0] == 0) \
@ -72,7 +49,7 @@ struct ip6_hdr {
} ip6_ctlun;
struct in6_addr ip6_src;
struct in6_addr ip6_dst;
} __attribute__ ((__packed__));
} __attribute__ ((__gcc_struct__, __packed__));
#define ip6_vfc ip6_ctlun.ip6_un2_vfc
#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
@ -91,7 +68,7 @@ struct icmp6_hdr {
uint16_t icmp6_un_data16[2];
uint8_t icmp6_un_data8[4];
} icmp6_dataun;
} __attribute__ ((__packed__));
} __attribute__ ((__gcc_struct__, __packed__));
#define ICMP6_DST_UNREACH_NOROUTE 0
#define ICMP6_DST_UNREACH 1
#define ICMP6_PACKET_TOO_BIG 2
@ -111,7 +88,7 @@ struct icmp6_hdr {
struct nd_neighbor_solicit {
struct icmp6_hdr nd_ns_hdr;
struct in6_addr nd_ns_target;
} __attribute__ ((__packed__));
} __attribute__ ((__gcc_struct__, __packed__));
#define ND_OPT_SOURCE_LINKADDR 1
#define ND_OPT_TARGET_LINKADDR 2
#define nd_ns_type nd_ns_hdr.icmp6_type
@ -124,7 +101,7 @@ struct nd_neighbor_solicit {
struct nd_opt_hdr {
uint8_t nd_opt_type;
uint8_t nd_opt_len;
} __attribute__ ((__packed__));
} __attribute__ ((__gcc_struct__, __packed__));
#endif
#endif /* __TINC_IPV6_H__ */

View file

@ -101,6 +101,9 @@ static bool setup_device(void) {
strncpy(ifrname, ifr.ifr_name, IFNAMSIZ);
free(iface);
iface = xstrdup(ifrname);
} else {
logger(DEBUG_ALWAYS, LOG_ERR, "Could not create a tun/tap interface from %s: %s", device, strerror(errno));
return false;
}
logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info);

View file

@ -79,6 +79,12 @@ extern void list_delete_list(list_t *);
extern void list_foreach(list_t *, list_action_t);
extern void list_foreach_node(list_t *, list_action_node_t);
/*
Iterates over a list.
CAUTION: while this construct supports deleting the current item,
it does *not* support deleting *other* nodes while iterating on the list.
*/
#define list_each(type, item, list) (type *item = (type *)1; item; item = NULL) for(list_node_t *node = (list)->head, *next; item = node ? node->data : NULL, next = node ? node->next : NULL, node; node = next)
#endif /* __TINC_LIST_H__ */

View file

@ -1,6 +1,6 @@
/*
logger.c -- logging code
Copyright (C) 2004-2013 Guus Sliepen <guus@tinc-vpn.org>
Copyright (C) 2004-2015 Guus Sliepen <guus@tinc-vpn.org>
2004-2005 Ivo Timmermans
This program is free software; you can redistribute it and/or modify
@ -26,6 +26,7 @@
#include "logger.h"
#include "connection.h"
#include "control_common.h"
#include "process.h"
#include "sptps.h"
debug_t debug_level = DEBUG_NOTHING;
@ -37,7 +38,7 @@ static HANDLE loghandle = NULL;
#endif
static const char *logident = NULL;
bool logcontrol = false;
int umbilical = 0;
static void real_logger(int level, int priority, const char *message) {
char timestr[32] = "";
@ -79,6 +80,11 @@ static void real_logger(int level, int priority, const char *message) {
case LOGMODE_NULL:
break;
}
if(umbilical && do_detach) {
write(umbilical, message, strlen(message));
write(umbilical, "\n", 1);
}
}
if(logcontrol) {
@ -114,9 +120,19 @@ void logger(int level, int priority, const char *format, ...) {
static void sptps_logger(sptps_t *s, int s_errno, const char *format, va_list ap) {
char message[1024] = "";
int len = vsnprintf(message, sizeof message, format, ap);
if(len > 0 && len < sizeof message && message[len - 1] == '\n')
message[len - 1] = 0;
size_t msglen = sizeof message;
int len = vsnprintf(message, msglen, format, ap);
if(len > 0 && len < sizeof message) {
if(message[len - 1] == '\n')
message[--len] = 0;
// WARNING: s->handle can point to a connection_t or a node_t,
// but both types have the name and hostname fields at the same offsets.
connection_t *c = s->handle;
if(c)
snprintf(message + len, sizeof message - len, " from %s (%s)", c->name, c->hostname);
}
real_logger(DEBUG_ALWAYS, LOG_ERR, message);
}
@ -194,6 +210,5 @@ void closelogger(void) {
case LOGMODE_NULL:
case LOGMODE_STDERR:
break;
break;
}
}

View file

@ -69,6 +69,7 @@ enum {
extern debug_t debug_level;
extern bool logcontrol;
extern int umbilical;
extern void openlogger(const char *, logmode_t);
extern void reopenlogger(void);
extern void logger(int, int, const char *, ...) __attribute__ ((__format__(printf, 3, 4)));

View file

@ -30,6 +30,10 @@
#include "utils.h"
#include "xalloc.h"
#ifndef MIN
#define MIN(x, y) (((x)<(y))?(x):(y))
#endif
bool send_meta_sptps(void *handle, uint8_t type, const void *buffer, size_t length) {
connection_t *c = handle;
@ -58,6 +62,9 @@ bool send_meta(connection_t *c, const char *buffer, int length) {
/* Add our data to buffer */
if(c->status.encryptout) {
#ifdef DISABLE_LEGACY
return false;
#else
size_t outlen = length;
if(!cipher_encrypt(c->outcipher, buffer, length, buffer_prepare(&c->outbuf, length), &outlen, false) || outlen != length) {
@ -65,6 +72,7 @@ bool send_meta(connection_t *c, const char *buffer, int length) {
c->name, c->hostname);
return false;
}
#endif
} else {
buffer_add(&c->outbuf, buffer, length);
}
@ -74,6 +82,20 @@ bool send_meta(connection_t *c, const char *buffer, int length) {
return true;
}
void send_meta_raw(connection_t *c, const char *buffer, int length) {
if(!c) {
logger(DEBUG_ALWAYS, LOG_ERR, "send_meta() called with NULL pointer!");
abort();
}
logger(DEBUG_META, LOG_DEBUG, "Sending %d bytes of raw metadata to %s (%s)", length,
c->name, c->hostname);
buffer_add(&c->outbuf, buffer, length);
io_set(&c->io, IO_READ | IO_WRITE);
}
void broadcast_meta(connection_t *from, const char *buffer, int length) {
for list_each(connection_t, c, connection_list)
if(c != from && c->edge)
@ -155,8 +177,33 @@ bool receive_meta(connection_t *c) {
}
do {
if(c->protocol_minor >= 2)
return sptps_receive_data(&c->sptps, bufp, inlen);
/* Are we receiving a SPTPS packet? */
if(c->sptpslen) {
int len = MIN(inlen, c->sptpslen - c->inbuf.len);
buffer_add(&c->inbuf, bufp, len);
char *sptpspacket = buffer_read(&c->inbuf, c->sptpslen);
if(!sptpspacket)
return true;
if(!receive_tcppacket_sptps(c, sptpspacket, c->sptpslen))
return false;
c->sptpslen = 0;
bufp += len;
inlen -= len;
continue;
}
if(c->protocol_minor >= 2) {
int len = sptps_receive_data(&c->sptps, bufp, inlen);
if(!len)
return false;
bufp += len;
inlen -= len;
continue;
}
if(!c->status.decryptin) {
endp = memchr(bufp, '\n', inlen);
@ -170,6 +217,9 @@ bool receive_meta(connection_t *c) {
inlen -= endp - bufp;
bufp = endp;
} else {
#ifdef DISABLE_LEGACY
return false;
#else
size_t outlen = inlen;
if(!cipher_decrypt(c->incipher, bufp, inlen, buffer_prepare(&c->inbuf, inlen), &outlen, false) || inlen != outlen) {
@ -179,6 +229,7 @@ bool receive_meta(connection_t *c) {
}
inlen = 0;
#endif
}
while(c->inbuf.len) {

View file

@ -24,6 +24,7 @@
#include "connection.h"
extern bool send_meta(struct connection_t *, const char *, int);
extern void send_meta_raw(struct connection_t *, const char *, int);
extern bool send_meta_sptps(void *, uint8_t, const void *, size_t);
extern bool receive_meta_sptps(void *, uint8_t, const void *, uint16_t);
extern void broadcast_meta(struct connection_t *, const char *, int);

View file

@ -38,7 +38,9 @@ int device_fd = -1;
static HANDLE device_handle = INVALID_HANDLE_VALUE;
static io_t device_read_io;
static OVERLAPPED device_read_overlapped;
static OVERLAPPED device_write_overlapped;
static vpn_packet_t device_read_packet;
static vpn_packet_t device_write_packet;
char *device = NULL;
char *iface = NULL;
static char *device_info = NULL;
@ -99,6 +101,9 @@ static bool setup_device(void) {
get_config_string(lookup_config(config_tree, "Device"), &device);
get_config_string(lookup_config(config_tree, "Interface"), &iface);
if(device && iface)
logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: both Device and Interface specified, results may not be as expected");
/* Open registry and look for network adapters */
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, NETWORK_CONNECTIONS_KEY, 0, KEY_READ, &key)) {
@ -175,6 +180,25 @@ static bool setup_device(void) {
return false;
}
/* Get version information from tap device */
{
ULONG info[3] = {0};
DWORD len;
if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_VERSION, &info, sizeof info, &info, sizeof info, &len, NULL))
logger(DEBUG_ALWAYS, LOG_WARNING, "Could not get version information from Windows tap device %s (%s): %s", device, iface, winerror(GetLastError()));
else {
logger(DEBUG_ALWAYS, LOG_INFO, "TAP-Windows driver version: %lu.%lu%s", info[0], info[1], info[2] ? " (DEBUG)" : "");
/* Warn if using >=9.21. This is because starting from 9.21, TAP-Win32 seems to use a different, less efficient write path. */
if(info[0] == 9 && info[1] >= 21)
logger(DEBUG_ALWAYS, LOG_WARNING,
"You are using the newer (>= 9.0.0.21, NDIS6) series of TAP-Win32 drivers. "
"Using these drivers with tinc is not recommanded as it can result in poor performance. "
"You might want to revert back to 9.0.0.9 instead.");
}
}
/* 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)) {
@ -200,8 +224,12 @@ static void enable_device(void) {
DWORD len;
DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof status, &status, sizeof status, &len, NULL);
io_add_event(&device_read_io, device_handle_read, NULL, CreateEvent(NULL, TRUE, FALSE, NULL));
device_read_overlapped.hEvent = device_read_io.event;
/* We don't use the write event directly, but GetOverlappedResult() does, internally. */
device_read_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
device_write_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
io_add_event(&device_read_io, device_handle_read, NULL, device_read_overlapped.hEvent);
device_issue_read();
}
@ -210,10 +238,22 @@ static void disable_device(void) {
io_del(&device_read_io);
CancelIo(device_handle);
/* According to MSDN, CancelIo() does not necessarily wait for the operation to complete.
To prevent race conditions, make sure the operation is complete
before we close the event it's referencing. */
DWORD len;
if(!GetOverlappedResult(device_handle, &device_read_overlapped, &len, TRUE) && GetLastError() != ERROR_OPERATION_ABORTED)
logger(DEBUG_ALWAYS, LOG_ERR, "Could not wait for %s %s read to cancel: %s", device_info, device, winerror(GetLastError()));
if(device_write_packet.len > 0 && !GetOverlappedResult(device_handle, &device_write_overlapped, &len, TRUE) && GetLastError() != ERROR_OPERATION_ABORTED)
logger(DEBUG_ALWAYS, LOG_ERR, "Could not wait for %s %s write to cancel: %s", device_info, device, winerror(GetLastError()));
device_write_packet.len = 0;
CloseHandle(device_read_overlapped.hEvent);
CloseHandle(device_write_overlapped.hEvent);
ULONG status = 0;
DWORD len;
DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof status, &status, sizeof status, &len, NULL);
}
@ -231,12 +271,29 @@ static bool read_packet(vpn_packet_t *packet) {
static bool write_packet(vpn_packet_t *packet) {
DWORD outlen;
OVERLAPPED overlapped = {0};
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s",
packet->len, device_info);
if(!WriteFile(device_handle, DATA(packet), packet->len, &outlen, &overlapped)) {
if(device_write_packet.len > 0) {
/* Make sure the previous write operation is finished before we start the next one;
otherwise we end up with multiple write ops referencing the same OVERLAPPED structure,
which according to MSDN is a no-no. */
if(!GetOverlappedResult(device_handle, &device_write_overlapped, &outlen, FALSE)) {
int log_level = (GetLastError() == ERROR_IO_INCOMPLETE) ? DEBUG_TRAFFIC : DEBUG_ALWAYS;
logger(log_level, LOG_ERR, "Error while checking previous write to %s %s: %s", device_info, device, winerror(GetLastError()));
return false;
}
}
/* Copy the packet, since the write operation might still be ongoing after we return. */
memcpy(&device_write_packet, packet, sizeof *packet);
if(WriteFile(device_handle, DATA(&device_write_packet), device_write_packet.len, &outlen, &device_write_overlapped))
device_write_packet.len = 0;
else if (GetLastError() != ERROR_IO_PENDING) {
logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, device, winerror(GetLastError()));
return false;
}

View file

@ -162,7 +162,7 @@ static void close_device(void) {
static bool read_packet(vpn_packet_t *packet) {
int lenin;
if((lenin = recv(device_fd, DATA(packet), MTU, 0)) <= 0) {
if((lenin = recv(device_fd, (void *)DATA(packet), MTU, 0)) <= 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info,
device, sockstrerror(sockerrno));
return false;
@ -185,7 +185,7 @@ static bool write_packet(vpn_packet_t *packet) {
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s",
packet->len, device_info);
if(sendto(device_fd, DATA(packet), packet->len, 0, ai->ai_addr, ai->ai_addrlen) < 0) {
if(sendto(device_fd, (void *)DATA(packet), packet->len, 0, ai->ai_addr, ai->ai_addrlen) < 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device,
sockstrerror(sockerrno));
return false;

View file

@ -1,7 +1,7 @@
/*
names.c -- generate commonly used (file)names
Copyright (C) 1998-2005 Ivo Timmermans
2000-2013 Guus Sliepen <guus@tinc-vpn.org>
2000-2015 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -21,6 +21,7 @@
#include "system.h"
#include "logger.h"
#include "names.h"
#include "xalloc.h"
char *netname = NULL;
@ -36,7 +37,7 @@ char *program_name = NULL;
/*
Set all files and paths according to netname
*/
void make_names(void) {
void make_names(bool daemon) {
#ifdef HAVE_MINGW
HKEY key;
char installdir[1024] = "";
@ -56,14 +57,14 @@ void make_names(void) {
if(!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\tinc", 0, KEY_READ, &key)) {
if(!RegQueryValueEx(key, NULL, 0, 0, (LPBYTE)installdir, &len)) {
confdir = xstrdup(installdir);
if(!logfilename)
xasprintf(&logfilename, "%s" SLASH "log" SLASH "%s.log", installdir, identname);
if(!confbase) {
if(netname)
xasprintf(&confbase, "%s" SLASH "%s", installdir, netname);
else
xasprintf(&confbase, "%s", installdir);
}
if(!logfilename)
xasprintf(&logfilename, "%s" SLASH "tinc.log", confbase);
}
RegCloseKey(key);
}
@ -85,21 +86,46 @@ void make_names(void) {
if(!pidfilename)
xasprintf(&pidfilename, "%s" SLASH "pid", confbase);
#else
bool fallback = false;
if(daemon) {
if(access(LOCALSTATEDIR, R_OK | W_OK | X_OK))
fallback = true;
} else {
char fname[PATH_MAX];
snprintf(fname, sizeof fname, LOCALSTATEDIR SLASH "run" SLASH "%s.pid", identname);
if(access(fname, R_OK)) {
snprintf(fname, sizeof fname, "%s" SLASH "pid", confbase);
if(!access(fname, R_OK))
fallback = true;
}
}
if(!fallback) {
if(!logfilename)
xasprintf(&logfilename, LOCALSTATEDIR SLASH "log" SLASH "%s.log", identname);
if(!pidfilename)
xasprintf(&pidfilename, LOCALSTATEDIR SLASH "run" SLASH "%s.pid", identname);
} else {
if(!logfilename)
xasprintf(&logfilename, "%s" SLASH "log", confbase);
if(!pidfilename) {
if(daemon)
logger(DEBUG_ALWAYS, LOG_WARNING, "Could not access " LOCALSTATEDIR SLASH " (%s), storing pid and socket files in %s" SLASH, strerror(errno), confbase);
xasprintf(&pidfilename, "%s" SLASH "pid", confbase);
}
}
#endif
if(!unixsocketname) {
int len = strlen(pidfilename);
unixsocketname = xmalloc(len + 8);
strcpy(unixsocketname, pidfilename);
memcpy(unixsocketname, pidfilename, len);
if(len > 4 && !strcmp(pidfilename + len - 4, ".pid"))
strcpy(unixsocketname + len - 4, ".socket");
strncpy(unixsocketname + len - 4, ".socket", 8);
else
strcpy(unixsocketname + len, ".socket");
strncpy(unixsocketname + len, ".socket", 8);
}
}
@ -111,4 +137,12 @@ void free_names(void) {
free(logfilename);
free(confbase);
free(confdir);
identname = NULL;
netname = NULL;
unixsocketname = NULL;
pidfilename = NULL;
logfilename = NULL;
confbase = NULL;
confdir = NULL;
}

View file

@ -1,7 +1,7 @@
/*
names.h -- header for names.c
Copyright (C) 1998-2005 Ivo Timmermans
2000-2013 Guus Sliepen <guus@tinc-vpn.org>
2000-2015 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
@ -31,7 +31,7 @@ extern char *logfilename;
extern char *pidfilename;
extern char *program_name;
extern void make_names(void);
extern void make_names(bool daemon);
extern void free_names(void);
#endif /* __TINC_NAMES_H__ */

View file

@ -1,7 +1,7 @@
/*
net.c -- most of the network code
Copyright (C) 1998-2005 Ivo Timmermans,
2000-2013 Guus Sliepen <guus@tinc-vpn.org>
2000-2015 Guus Sliepen <guus@tinc-vpn.org>
2006 Scott Lamb <slamb@slamb.org>
2011 Loïc Grenié <loic.grenie@gmail.com>
@ -36,10 +36,6 @@
#include "subnet.h"
#include "xalloc.h"
#ifdef HAVE_RESOLV_H
#include <resolv.h>
#endif
int contradicting_add_edge = 0;
int contradicting_del_edge = 0;
static int sleeptime = 10;
@ -154,8 +150,9 @@ static void timeout_handler(void *data) {
if(c->last_ping_time + pingtimeout <= now.tv_sec) {
if(c->edge) {
try_tx(c->node, false);
if(c->status.pinged) {
logger(DEBUG_CONNECTIONS, LOG_INFO, "%s (%s) didn't respond to PING in %ld seconds", c->name, c->hostname, (long)now.tv_sec - c->last_ping_time);
logger(DEBUG_CONNECTIONS, LOG_INFO, "%s (%s) didn't respond to PING in %ld seconds", c->name, c->hostname, (long)(now.tv_sec - c->last_ping_time));
} else if(c->last_ping_time + pinginterval <= now.tv_sec) {
send_ping(c);
continue;
@ -170,9 +167,10 @@ static void timeout_handler(void *data) {
}
terminate_connection(c, c->edge);
}
}
timeout_set(data, &(struct timeval){pingtimeout, rand() % 100000});
timeout_set(data, &(struct timeval){1, rand() % 100000});
}
static void periodic_handler(void *data) {
@ -183,7 +181,7 @@ static void periodic_handler(void *data) {
if(contradicting_del_edge > 100 && contradicting_add_edge > 100) {
logger(DEBUG_ALWAYS, LOG_WARNING, "Possible node with same Name as us! Sleeping %d seconds.", sleeptime);
usleep(sleeptime * 1000000LL);
nanosleep(&(struct timespec){sleeptime, 0}, NULL);
sleeptime *= 2;
if(sleeptime < 0)
sleeptime = 3600;
@ -212,10 +210,13 @@ static void periodic_handler(void *data) {
and we are not already trying to make one, create an
outgoing connection to this node.
*/
int r = rand() % node_tree->count;
int r = rand() % (node_tree->count - 1);
int i = 0;
for splay_each(node_t, n, node_tree) {
if(n == myself)
continue;
if(i++ != r)
continue;
@ -311,15 +312,12 @@ static void sighup_handler(void *data) {
static void sigalrm_handler(void *data) {
logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum));
#ifdef HAVE_DECL_RES_INIT
res_init();
#endif
retry();
}
#endif
int reload_configuration(void) {
char *fname = NULL;
char fname[PATH_MAX];
/* Reread our own configuration file */
@ -333,9 +331,8 @@ int reload_configuration(void) {
read_config_options(config_tree, NULL);
xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, myself->name);
snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, myself->name);
read_config_file(config_tree, fname);
free(fname);
/* Parse some options that are allowed to be changed while tinc is running */
@ -412,13 +409,12 @@ int reload_configuration(void) {
if(c->status.control)
continue;
xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, c->name);
snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, c->name);
struct stat s;
if(stat(fname, &s) || s.st_mtime > last_config_check) {
logger(DEBUG_CONNECTIONS, LOG_INFO, "Host config file of %s has been changed", c->name);
terminate_connection(c, c->edge);
}
free(fname);
}
last_config_check = now.tv_sec;
@ -449,7 +445,7 @@ void retry(void) {
*/
int main_loop(void) {
timeout_add(&pingtimer, timeout_handler, &pingtimer, &(struct timeval){pingtimeout, rand() % 100000});
timeout_add(&periodictimer, periodic_handler, &periodictimer, &(struct timeval){pingtimeout, rand() % 100000});
timeout_add(&periodictimer, periodic_handler, &periodictimer, &(struct timeval){0, 0});
#ifndef HAVE_MINGW
signal_t sighup = {0};

View file

@ -1,7 +1,7 @@
/*
net.h -- header for net.c
Copyright (C) 1998-2005 Ivo Timmermans
2000-2014 Guus Sliepen <guus@tinc-vpn.org>
2000-2016 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -115,6 +115,7 @@ typedef struct listen_socket_t {
io_t udp;
sockaddr_t sa;
bool bindto;
int priority;
} listen_socket_t;
#include "conf.h"
@ -138,6 +139,14 @@ extern int addressfamily;
extern unsigned replaywin;
extern bool localdiscovery;
extern bool udp_discovery;
extern int udp_discovery_keepalive_interval;
extern int udp_discovery_interval;
extern int udp_discovery_timeout;
extern int mtu_info_interval;
extern int udp_info_interval;
extern listen_socket_t listen_socket[MAXSOCKETS];
extern int listen_sockets;
extern io_t unix_socket;
@ -183,10 +192,11 @@ extern void handle_new_meta_connection(void *, int);
extern void handle_new_unix_connection(void *, int);
extern int setup_listen_socket(const sockaddr_t *);
extern int setup_vpn_in_socket(const sockaddr_t *);
extern bool send_sptps_data(void *handle, uint8_t type, const void *data, size_t len);
extern bool send_sptps_data(node_t *to, node_t *from, int type, const void *data, size_t len);
extern bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t len);
extern void send_packet(struct node_t *, vpn_packet_t *);
extern void receive_tcppacket(struct connection_t *, const char *, int);
extern bool receive_tcppacket_sptps(struct connection_t *, const char *, int);
extern void broadcast_packet(const struct node_t *, vpn_packet_t *);
extern char *get_name(void);
extern void device_enable(void);
@ -201,7 +211,6 @@ extern void terminate_connection(struct connection_t *, bool);
extern bool node_read_ecdsa_public_key(struct node_t *);
extern bool read_ecdsa_public_key(struct connection_t *);
extern bool read_rsa_public_key(struct connection_t *);
extern void send_mtu_probe(struct node_t *);
extern void handle_device_data(void *, int);
extern void handle_meta_connection_data(struct connection_t *);
extern void regenerate_key(void);
@ -210,6 +219,7 @@ extern void retry(void);
extern int reload_configuration(void);
extern void load_all_subnets(void);
extern void load_all_nodes(void);
extern void try_tx(struct node_t *n, bool);
#ifndef HAVE_MINGW
#define closesocket(s) close(s)

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
/*
net_setup.c -- Setup.
Copyright (C) 1998-2005 Ivo Timmermans,
2000-2014 Guus Sliepen <guus@tinc-vpn.org>
2000-2016 Guus Sliepen <guus@tinc-vpn.org>
2006 Scott Lamb <slamb@slamb.org>
2010 Brandon Black <blblack@gmail.com>
@ -43,6 +43,10 @@
#include "utils.h"
#include "xalloc.h"
#ifdef HAVE_MINIUPNPC
#include "upnp.h"
#endif
char *myport;
static char *myname;
static io_t device_io;
@ -137,18 +141,17 @@ bool read_ecdsa_public_key(connection_t *c) {
}
c->ecdsa = ecdsa_read_pem_public_key(fp);
fclose(fp);
if(!c->ecdsa)
if(!c->ecdsa && errno != ENOENT)
logger(DEBUG_ALWAYS, LOG_ERR, "Parsing Ed25519 public key file `%s' failed.", fname);
fclose(fp);
free(fname);
return c->ecdsa;
}
#ifndef DISABLE_LEGACY
bool read_rsa_public_key(connection_t *c) {
if(ecdsa_active(c->ecdsa))
return true;
FILE *fp;
char *fname;
char *n;
@ -182,6 +185,7 @@ bool read_rsa_public_key(connection_t *c) {
free(fname);
return c->rsa;
}
#endif
static bool read_ecdsa_private_key(void) {
FILE *fp;
@ -226,14 +230,14 @@ static bool read_ecdsa_private_key(void) {
static bool read_invitation_key(void) {
FILE *fp;
char *fname;
char fname[PATH_MAX];
if(invitation_key) {
ecdsa_free(invitation_key);
invitation_key = NULL;
}
xasprintf(&fname, "%s" SLASH "invitations" SLASH "ed25519_key.priv", confbase);
snprintf(fname, sizeof fname, "%s" SLASH "invitations" SLASH "ed25519_key.priv", confbase);
fp = fopen(fname, "r");
@ -244,10 +248,10 @@ static bool read_invitation_key(void) {
logger(DEBUG_ALWAYS, LOG_ERR, "Reading Ed25519 private key file `%s' failed", fname);
}
free(fname);
return invitation_key;
}
#ifndef DISABLE_LEGACY
static bool read_rsa_private_key(void) {
FILE *fp;
char *fname;
@ -304,6 +308,7 @@ static bool read_rsa_private_key(void) {
free(fname);
return myself->connection->rsa;
}
#endif
static timeout_t keyexpire_timeout;
@ -315,6 +320,8 @@ static void keyexpire_handler(void *data) {
void regenerate_key(void) {
logger(DEBUG_STATUS, LOG_INFO, "Expiring symmetric keys");
send_key_changed();
for splay_each(node_t, n, node_tree)
n->status.validkey_in = false;
}
/*
@ -323,13 +330,12 @@ void regenerate_key(void) {
void load_all_subnets(void) {
DIR *dir;
struct dirent *ent;
char *dname;
char dname[PATH_MAX];
xasprintf(&dname, "%s" SLASH "hosts", confbase);
snprintf(dname, sizeof dname, "%s" SLASH "hosts", confbase);
dir = opendir(dname);
if(!dir) {
logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", dname, strerror(errno));
free(dname);
return;
}
@ -362,6 +368,7 @@ void load_all_subnets(void) {
if((s2 = lookup_subnet(n, s))) {
s2->expires = -1;
free(s);
} else {
subnet_add(n, s);
}
@ -376,13 +383,12 @@ void load_all_subnets(void) {
void load_all_nodes(void) {
DIR *dir;
struct dirent *ent;
char *dname;
char dname[PATH_MAX];
xasprintf(&dname, "%s" SLASH "hosts", confbase);
snprintf(dname, sizeof dname, "%s" SLASH "hosts", confbase);
dir = opendir(dname);
if(!dir) {
logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", dname, strerror(errno));
free(dname);
return;
}
@ -506,6 +512,14 @@ bool setup_myself_reloadable(void) {
if(myself->options & OPTION_TCPONLY)
myself->options |= OPTION_INDIRECT;
get_config_bool(lookup_config(config_tree, "UDPDiscovery"), &udp_discovery);
get_config_int(lookup_config(config_tree, "UDPDiscoveryKeepaliveInterval"), &udp_discovery_keepalive_interval);
get_config_int(lookup_config(config_tree, "UDPDiscoveryInterval"), &udp_discovery_interval);
get_config_int(lookup_config(config_tree, "UDPDiscoveryTimeout"), &udp_discovery_timeout);
get_config_int(lookup_config(config_tree, "MTUInfoInterval"), &mtu_info_interval);
get_config_int(lookup_config(config_tree, "UDPInfoInterval"), &udp_info_interval);
get_config_bool(lookup_config(config_tree, "DirectOnly"), &directonly);
get_config_bool(lookup_config(config_tree, "LocalDiscovery"), &localdiscovery);
@ -577,9 +591,14 @@ bool setup_myself_reloadable(void) {
subnet_add(NULL, s);
}
#if !defined(SOL_IP) || !defined(IP_TOS)
#if !defined(IPPROTO_IP) || !defined(IP_TOS)
if(priorityinheritance)
logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform", "PriorityInheritance");
logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform for IPv4 connections", "PriorityInheritance");
#endif
#if !defined(IPPROTO_IPV6) || !defined(IPV6_TCLASS)
if(priorityinheritance)
logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform for IPv6 connections", "PriorityInheritance");
#endif
if(!get_config_int(lookup_config(config_tree, "MACExpire"), &macexpire))
@ -652,6 +671,9 @@ static bool add_listen_address(char *address, bool bindto) {
hint.ai_protocol = IPPROTO_TCP;
hint.ai_flags = AI_PASSIVE;
#if HAVE_DECL_RES_INIT
res_init();
#endif
int err = getaddrinfo(address && *address ? address : NULL, port, &hint, &ai);
free(address);
@ -773,6 +795,13 @@ static bool setup_myself(void) {
myself->options |= PROT_MINOR << 24;
#ifdef DISABLE_LEGACY
experimental = read_ecdsa_private_key();
if(!experimental) {
logger(DEBUG_ALWAYS, LOG_ERR, "No private key available, cannot start tinc!");
return false;
}
#else
if(!get_config_bool(lookup_config(config_tree, "ExperimentalProtocol"), &experimental)) {
experimental = read_ecdsa_private_key();
if(!experimental)
@ -790,6 +819,7 @@ static bool setup_myself(void) {
return false;
}
}
#endif
/* Ensure myport is numeric */
@ -831,14 +861,14 @@ static bool setup_myself(void) {
}
if(get_config_int(lookup_config(config_tree, "UDPRcvBuf"), &udp_rcvbuf)) {
if(udp_rcvbuf <= 0) {
if(udp_rcvbuf < 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "UDPRcvBuf cannot be negative!");
return false;
}
}
if(get_config_int(lookup_config(config_tree, "UDPSndBuf"), &udp_sndbuf)) {
if(udp_sndbuf <= 0) {
if(udp_sndbuf < 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "UDPSndBuf cannot be negative!");
return false;
}
@ -854,6 +884,7 @@ static bool setup_myself(void) {
sptps_replaywin = replaywin;
}
#ifndef DISABLE_LEGACY
/* Generate packet encryption key */
if(!get_config_string(lookup_config(config_tree, "Cipher"), &cipher))
@ -891,6 +922,7 @@ static bool setup_myself(void) {
}
free(digest);
#endif
/* Compression */
@ -939,6 +971,7 @@ static bool setup_myself(void) {
else if(!strcasecmp(type, "vde"))
devops = vde_devops;
#endif
free(type);
}
get_config_bool(lookup_config(config_tree, "DeviceStandby"), &device_standby);
@ -1035,6 +1068,25 @@ static bool setup_myself(void) {
xasprintf(&myself->hostname, "MYSELF port %s", myport);
myself->connection->hostname = xstrdup(myself->hostname);
char *upnp = NULL;
get_config_string(lookup_config(config_tree, "UPnP"), &upnp);
bool upnp_tcp = false;
bool upnp_udp = false;
if (upnp) {
if (!strcasecmp(upnp, "yes"))
upnp_tcp = upnp_udp = true;
else if (!strcasecmp(upnp, "udponly"))
upnp_udp = true;
free(upnp);
}
if (upnp_tcp || upnp_udp) {
#ifdef HAVE_MINIUPNPC
upnp_init(upnp_tcp, upnp_udp);
#else
logger(DEBUG_ALWAYS, LOG_WARNING, "UPnP was requested, but tinc isn't built with miniupnpc support!");
#endif
}
/* Done. */
last_config_check = now.tv_sec;
@ -1102,8 +1154,7 @@ void close_network_connections(void) {
if(myself && myself->connection) {
subnet_update(myself, NULL, false);
terminate_connection(myself->connection, false);
free_connection(myself->connection);
connection_del(myself->connection);
}
for(int i = 0; i < listen_sockets; i++) {

View file

@ -1,7 +1,7 @@
/*
net_socket.c -- Handle various kinds of sockets.
Copyright (C) 1998-2005 Ivo Timmermans,
2000-2014 Guus Sliepen <guus@tinc-vpn.org>
2000-2016 Guus Sliepen <guus@tinc-vpn.org>
2006 Scott Lamb <slamb@slamb.org>
2009 Florian Forster <octo@verplant.org>
@ -35,16 +35,11 @@
#include "utils.h"
#include "xalloc.h"
/* Needed on Mac OS/X */
#ifndef SOL_TCP
#define SOL_TCP IPPROTO_TCP
#endif
int addressfamily = AF_UNSPEC;
int maxtimeout = 900;
int seconds_till_retry = 5;
int udp_rcvbuf = 0;
int udp_sndbuf = 0;
int udp_rcvbuf = 1024 * 1024;
int udp_sndbuf = 1024 * 1024;
int max_connection_burst = 100;
listen_socket_t listen_socket[MAXSOCKETS];
@ -73,14 +68,19 @@ static void configure_tcp(connection_t *c) {
}
#endif
#if defined(SOL_TCP) && defined(TCP_NODELAY)
#if defined(IPPROTO_TCP) && defined(TCP_NODELAY)
option = 1;
setsockopt(c->socket, SOL_TCP, TCP_NODELAY, (void *)&option, sizeof option);
setsockopt(c->socket, IPPROTO_TCP, TCP_NODELAY, (void *)&option, sizeof option);
#endif
#if defined(SOL_IP) && defined(IP_TOS) && defined(IPTOS_LOWDELAY)
#if defined(IPPROTO_IP) && defined(IP_TOS) && defined(IPTOS_LOWDELAY)
option = IPTOS_LOWDELAY;
setsockopt(c->socket, SOL_IP, IP_TOS, (void *)&option, sizeof option);
setsockopt(c->socket, IPPROTO_IP, IP_TOS, (void *)&option, sizeof option);
#endif
#if defined(IPPROTO_IPV6) && defined(IPV6_TCLASS) && defined(IPTOS_LOWDELAY)
option = IPTOS_LOWDELAY;
setsockopt(c->socket, IPPROTO_IPV6, IPV6_TCLASS, (void *)&option, sizeof option);
#endif
}
@ -163,9 +163,9 @@ int setup_listen_socket(const sockaddr_t *sa) {
option = 1;
setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof option);
#if defined(SOL_IPV6) && defined(IPV6_V6ONLY)
#if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
if(sa->sa.sa_family == AF_INET6)
setsockopt(nfd, SOL_IPV6, IPV6_V6ONLY, (void *)&option, sizeof option);
setsockopt(nfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof option);
#endif
if(get_config_string
@ -261,10 +261,10 @@ int setup_vpn_in_socket(const sockaddr_t *sa) {
#define IP_DONTFRAGMENT IP_DONTFRAG
#endif
#if defined(SOL_IP) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
#if defined(IPPROTO_IP) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
if(myself->options & OPTION_PMTU_DISCOVERY) {
option = IP_PMTUDISC_DO;
setsockopt(nfd, SOL_IP, IP_MTU_DISCOVER, (void *)&option, sizeof(option));
setsockopt(nfd, IPPROTO_IP, IP_MTU_DISCOVER, (void *)&option, sizeof(option));
}
#elif defined(IPPROTO_IP) && defined(IP_DONTFRAGMENT)
if(myself->options & OPTION_PMTU_DISCOVERY) {
@ -273,10 +273,10 @@ int setup_vpn_in_socket(const sockaddr_t *sa) {
}
#endif
#if defined(SOL_IPV6) && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
#if defined(IPPROTO_IPV6) && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
if(myself->options & OPTION_PMTU_DISCOVERY) {
option = IPV6_PMTUDISC_DO;
setsockopt(nfd, SOL_IPV6, IPV6_MTU_DISCOVER, (void *)&option, sizeof(option));
setsockopt(nfd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, (void *)&option, sizeof(option));
}
#elif defined(IPPROTO_IPV6) && defined(IPV6_DONTFRAG)
if(myself->options & OPTION_PMTU_DISCOVERY) {
@ -517,10 +517,10 @@ begin:
#endif
if(proxytype != PROXY_EXEC) {
#if defined(SOL_IPV6) && defined(IPV6_V6ONLY)
#if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
int option = 1;
if(c->address.sa.sa_family == AF_INET6)
setsockopt(c->socket, SOL_IPV6, IPV6_V6ONLY, (void *)&option, sizeof option);
setsockopt(c->socket, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof option);
#endif
bind_to_interface(c->socket);
@ -547,10 +547,13 @@ begin:
/* Now that there is a working socket, fill in the rest and register this connection. */
c->last_ping_time = time(NULL);
c->status.connecting = true;
c->name = xstrdup(outgoing->name);
#ifndef DISABLE_LEGACY
c->outcipher = myself->connection->outcipher;
c->outdigest = myself->connection->outdigest;
#endif
c->outmaclength = myself->connection->outmaclength;
c->outcompression = myself->connection->outcompression;
c->last_ping_time = now.tv_sec;
@ -602,9 +605,12 @@ void setup_outgoing_connection(outgoing_t *outgoing) {
if(n && n->connection) {
logger(DEBUG_CONNECTIONS, LOG_INFO, "Already connected to %s", outgoing->name);
if(!n->connection->outgoing) {
n->connection->outgoing = outgoing;
return;
} else {
goto remove;
}
}
init_configuration(&outgoing->config_tree);
@ -615,12 +621,16 @@ void setup_outgoing_connection(outgoing_t *outgoing) {
if(n)
outgoing->aip = outgoing->ai = get_known_addresses(n);
if(!outgoing->ai) {
logger(DEBUG_ALWAYS, LOG_ERR, "No address known for %s", outgoing->name);
return;
logger(DEBUG_ALWAYS, LOG_DEBUG, "No address known for %s", outgoing->name);
goto remove;
}
}
do_outgoing_connection(outgoing);
return;
remove:
list_delete(outgoing_list, outgoing);
}
/*
@ -696,8 +706,10 @@ void handle_new_meta_connection(void *data, int flags) {
c = new_connection();
c->name = xstrdup("<unknown>");
#ifndef DISABLE_LEGACY
c->outcipher = myself->connection->outcipher;
c->outdigest = myself->connection->outdigest;
#endif
c->outmaclength = myself->connection->outmaclength;
c->outcompression = myself->connection->outcompression;
@ -796,6 +808,11 @@ void try_outgoing_connections(void) {
continue;
}
if(!strcmp(name, myself->name)) {
free(name);
continue;
}
bool found = false;
for list_each(outgoing_t, outgoing, outgoing_list) {

View file

@ -39,6 +39,9 @@ struct addrinfo *str2addrinfo(const char *address, const char *service, int sock
hint.ai_family = addressfamily;
hint.ai_socktype = socktype;
#if HAVE_DECL_RES_INIT
res_init();
#endif
err = getaddrinfo(address, service, &hint, &ai);
if(err) {
@ -80,7 +83,13 @@ void sockaddr2str(const sockaddr_t *sa, char **addrstr, char **portstr) {
char *scopeid;
int err;
if(sa->sa.sa_family == AF_UNKNOWN) {
if(sa->sa.sa_family == AF_UNSPEC) {
if(addrstr)
*addrstr = xstrdup("unspec");
if(portstr)
*portstr = xstrdup("unspec");
return;
} else if(sa->sa.sa_family == AF_UNKNOWN) {
if(addrstr)
*addrstr = xstrdup(sa->unknown.address);
if(portstr)
@ -112,7 +121,10 @@ char *sockaddr2hostname(const sockaddr_t *sa) {
char port[NI_MAXSERV] = "unknown";
int err;
if(sa->sa.sa_family == AF_UNKNOWN) {
if(sa->sa.sa_family == AF_UNSPEC) {
xasprintf(&str, "unspec port unspec");
return str;
} else if(sa->sa.sa_family == AF_UNKNOWN) {
xasprintf(&str, "%s port %s", sa->unknown.address, sa->unknown.port);
return str;
}

View file

@ -30,12 +30,11 @@
#include "utils.h"
#include "xalloc.h"
static digest_t *sha256;
#include "ed25519/sha512.h"
splay_tree_t *node_tree;
static splay_tree_t *node_id_tree;
static hash_t *node_udp_cache;
static hash_t *node_id_cache;
static splay_tree_t *node_udp_tree;
node_t *myself;
@ -47,22 +46,23 @@ static int node_id_compare(const node_t *a, const node_t *b) {
return memcmp(&a->id, &b->id, sizeof(node_id_t));
}
void init_nodes(void) {
sha256 = digest_open_by_name("sha256", sizeof(node_id_t));
static int node_udp_compare(const node_t *a, const node_t *b) {
int result = sockaddrcmp(&a->address, &b->address);
if (result)
return result;
return (a->name && b->name) ? strcmp(a->name, b->name) : 0;
}
void init_nodes(void) {
node_tree = splay_alloc_tree((splay_compare_t) node_compare, (splay_action_t) free_node);
node_id_tree = splay_alloc_tree((splay_compare_t) node_id_compare, NULL);
node_udp_cache = hash_alloc(0x100, sizeof(sockaddr_t));
node_id_cache = hash_alloc(0x100, sizeof(node_id_t));
node_udp_tree = splay_alloc_tree((splay_compare_t) node_udp_compare, NULL);
}
void exit_nodes(void) {
hash_free(node_id_cache);
hash_free(node_udp_cache);
splay_delete_tree(node_udp_tree);
splay_delete_tree(node_id_tree);
splay_delete_tree(node_tree);
digest_close(sha256);
}
node_t *new_node(void) {
@ -86,15 +86,17 @@ void free_node(node_t *n) {
sockaddrfree(&n->address);
#ifndef DISABLE_LEGACY
cipher_close(n->incipher);
digest_close(n->indigest);
cipher_close(n->outcipher);
digest_close(n->outdigest);
#endif
ecdsa_free(n->ecdsa);
sptps_stop(&n->sptps);
timeout_del(&n->mtutimeout);
timeout_del(&n->udp_ping_timeout);
if(n->hostname)
free(n->hostname);
@ -109,15 +111,16 @@ void free_node(node_t *n) {
}
void node_add(node_t *n) {
digest_create(sha256, n->name, strlen(n->name), &n->id);
unsigned char buf[64];
sha512(n->name, strlen(n->name),buf);
memcpy(&n->id, buf, sizeof n->id);
splay_insert(node_tree, n);
splay_insert(node_id_tree, n);
}
void node_del(node_t *n) {
hash_delete(node_udp_cache, &n->address);
hash_delete(node_id_cache, &n->id);
splay_delete(node_udp_tree, n);
for splay_each(subnet_t, s, n->subnet_tree)
subnet_del(n, s);
@ -138,19 +141,13 @@ node_t *lookup_node(char *name) {
}
node_t *lookup_node_id(const node_id_t *id) {
node_t *n = hash_search(node_id_cache, id);
if(!n) {
node_t tmp = {.id = *id};
n = splay_search(node_id_tree, &tmp);
if(n)
hash_insert(node_id_cache, id, n);
}
return n;
node_t n = {.id = *id};
return splay_search(node_id_tree, &n);
}
node_t *lookup_node_udp(const sockaddr_t *sa) {
return hash_search(node_udp_cache, sa);
node_t tmp = {.address = *sa};
return splay_search(node_udp_tree, &tmp);
}
void update_node_udp(node_t *n, const sockaddr_t *sa) {
@ -159,7 +156,7 @@ void update_node_udp(node_t *n, const sockaddr_t *sa) {
return;
}
hash_delete(node_udp_cache, &n->address);
splay_delete(node_udp_tree, n);
if(sa) {
n->address = *sa;
@ -170,7 +167,7 @@ void update_node_udp(node_t *n, const sockaddr_t *sa) {
break;
}
}
hash_insert(node_udp_cache, sa, n);
splay_insert(node_udp_tree, n);
free(n->hostname);
n->hostname = sockaddr2hostname(&n->address);
logger(DEBUG_PROTOCOL, LOG_DEBUG, "UDP address of %s set to %s", n->name, n->hostname);
@ -179,6 +176,7 @@ void update_node_udp(node_t *n, const sockaddr_t *sa) {
/* invalidate UDP information - note that this is a security feature as well to make sure
we can't be tricked into flooding any random address with UDP packets */
n->status.udp_confirmed = false;
n->maxrecentlen = 0;
n->mtuprobes = 0;
n->minmtu = 0;
n->maxmtu = MTU;
@ -188,13 +186,18 @@ bool dump_nodes(connection_t *c) {
for splay_each(node_t, n, node_tree) {
char id[2 * sizeof n->id + 1];
for (size_t c = 0; c < sizeof n->id; ++c)
sprintf(id + 2 * c, "%02hhx", n->id.x[c]);
snprintf(id + 2 * c, 3, "%02hhx", n->id.x[c]);
id[sizeof id - 1] = 0;
send_request(c, "%d %d %s %s %s %d %d %d %d %x %x %s %s %d %hd %hd %hd %ld", CONTROL, REQ_DUMP_NODES,
n->name, id, n->hostname ?: "unknown port unknown", cipher_get_nid(n->outcipher),
digest_get_nid(n->outdigest), (int)digest_length(n->outdigest), n->outcompression,
n->options, bitfield_to_int(&n->status, sizeof n->status), n->nexthop ? n->nexthop->name : "-",
n->via ? n->via->name ?: "-" : "-", n->distance, n->mtu, n->minmtu, n->maxmtu, (long)n->last_state_change);
n->name, id, n->hostname ?: "unknown port unknown",
#ifdef DISABLE_LEGACY
0, 0, 0,
#else
cipher_get_nid(n->outcipher), digest_get_nid(n->outdigest), (int)digest_length(n->outdigest),
#endif
n->outcompression, n->options, bitfield_to_int(&n->status, sizeof n->status),
n->nexthop ? n->nexthop->name : "-", n->via ? n->via->name ?: "-" : "-", n->distance,
n->mtu, n->minmtu, n->maxmtu, (long)n->last_state_change);
}
return send_request(c, "%d %d", CONTROL, REQ_DUMP_NODES);

View file

@ -38,17 +38,19 @@ typedef struct node_status_t {
unsigned int sptps:1; /* 1 if this node supports SPTPS */
unsigned int udp_confirmed:1; /* 1 if the address is one that we received UDP traffic on */
unsigned int send_locally:1; /* 1 if the next UDP packet should be sent on the local network */
unsigned int unused:23;
unsigned int udppacket:1; /* 1 if the most recently received packet was UDP */
unsigned int validkey_in:1; /* 1 if we have sent a valid key to him */
unsigned int unused:21;
} node_status_t;
typedef struct node_t {
char *name; /* name of this node */
char *hostname; /* the hostname of its real ip */
node_id_t id; /* unique node ID (name hash) */
uint32_t options; /* options turned on for this node */
int sock; /* Socket to use for outgoing UDP packets */
sockaddr_t address; /* his real (internet) ip to send UDP packets to */
char *hostname; /* the hostname of its real ip */
node_status_t status;
time_t last_state_change;
@ -57,11 +59,13 @@ typedef struct node_t {
ecdsa_t *ecdsa; /* His public ECDSA key */
sptps_t sptps;
#ifndef DISABLE_LEGACY
cipher_t *incipher; /* Cipher for UDP packets */
digest_t *indigest; /* Digest for UDP packets */
cipher_t *outcipher; /* Cipher for UDP packets */
digest_t *outdigest; /* Digest for UDP packets */
#endif
int incompression; /* Compressionlevel, 0 = no compression */
int outcompression; /* Compressionlevel, 0 = no compression */
@ -85,16 +89,21 @@ typedef struct node_t {
uint32_t farfuture; /* Packets in a row that have arrived from the far future */
unsigned char* late; /* Bitfield marking late packets */
struct timeval udp_reply_sent; /* Last time a (gratuitous) UDP probe reply was sent */
struct timeval udp_ping_sent; /* Last time a UDP probe was sent */
timeout_t udp_ping_timeout; /* Ping timeout event */
struct timeval mtu_ping_sent; /* Last time a MTU probe was sent */
struct timeval mtu_info_sent; /* Last time a MTU_INFO message was sent */
struct timeval udp_info_sent; /* Last time a UDP_INFO message was sent */
length_t maxrecentlen; /* Maximum size of recently received packets */
length_t mtu; /* Maximum size of packets to send to this node */
length_t minmtu; /* Probed minimum MTU */
length_t maxmtu; /* Probed maximum MTU */
int mtuprobes; /* Number of probes */
timeout_t mtutimeout; /* Probe event */
struct timeval probe_time; /* Time the last probe was sent or received */
int probe_counter; /* Number of probes received since last burst was sent */
float rtt; /* Last measured round trip time */
float bandwidth; /* Last measured bandwidth */
float packetloss; /* Last measured packet loss rate */
uint64_t in_packets;
uint64_t in_bytes;

87
src/nolegacy/crypto.c Normal file
View file

@ -0,0 +1,87 @@
/*
crypto.c -- Cryptographic miscellaneous functions and initialisation
Copyright (C) 2007-2014 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 "../crypto.h"
#ifndef HAVE_MINGW
static int random_fd = -1;
static void random_init(void) {
random_fd = open("/dev/urandom", O_RDONLY);
if(random_fd < 0)
random_fd = open("/dev/random", O_RDONLY);
if(random_fd < 0) {
fprintf(stderr, "Could not open source of random numbers: %s\n", strerror(errno));
abort();
}
}
static void random_exit(void) {
close(random_fd);
}
void randomize(void *out, size_t outlen) {
while(outlen) {
size_t len = read(random_fd, out, outlen);
if(len <= 0) {
if(errno == EAGAIN || errno == EINTR)
continue;
fprintf(stderr, "Could not read random numbers: %s\n", strerror(errno));
abort();
}
out += len;
outlen -= len;
}
}
#else
#include <wincrypt.h>
HCRYPTPROV prov;
void random_init(void) {
if(!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
fprintf(stderr, "CryptAcquireContext() failed!\n");
abort();
}
}
void random_exit(void) {
CryptReleaseContext(prov, 0);
}
void randomize(void *out, size_t outlen) {
if(!CryptGenRandom(prov, outlen, out)) {
fprintf(stderr, "CryptGenRandom() failed\n");
abort();
}
}
#endif
void crypto_init(void) {
random_init();
}
void crypto_exit(void) {
random_exit();
}

106
src/nolegacy/prf.c Normal file
View file

@ -0,0 +1,106 @@
/*
prf.c -- Pseudo-Random Function for key material generation
Copyright (C) 2011-2013 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 "../prf.h"
#include "../ed25519/sha512.h"
static void memxor(char *buf, char c, size_t len) {
for(size_t i = 0; i < len; i++)
buf[i] ^= c;
}
static const size_t mdlen = 64;
static const size_t blklen = 128;
static bool hmac_sha512(const char *key, size_t keylen, const char *msg, size_t msglen, char *out) {
char tmp[blklen + mdlen];
sha512_context md;
if(keylen <= blklen) {
memcpy(tmp, key, keylen);
memset(tmp + keylen, 0, blklen - keylen);
} else {
if(sha512(key, keylen, tmp) != 0)
return false;
memset(tmp + mdlen, 0, blklen - mdlen);
}
if(sha512_init(&md) != 0)
return false;
// ipad
memxor(tmp, 0x36, blklen);
if(sha512_update(&md, tmp, blklen) != 0)
return false;
// message
if(sha512_update(&md, msg, msglen) != 0)
return false;
if(sha512_final(&md, tmp + blklen) != 0)
return false;
// opad
memxor(tmp, 0x36 ^ 0x5c, blklen);
if(sha512(tmp, sizeof tmp, out) != 0)
return false;
return true;
}
/* Generate key material from a master secret and a seed, based on RFC 4346 section 5.
We use SHA512 instead of MD5 and SHA1.
*/
bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen) {
/* Data is what the "inner" HMAC function processes.
It consists of the previous HMAC result plus the seed.
*/
char data[mdlen + seedlen];
memset(data, 0, mdlen);
memcpy(data + mdlen, seed, seedlen);
char hash[mdlen];
while(outlen > 0) {
/* Inner HMAC */
if(!hmac_sha512(secret, secretlen, data, sizeof data, data))
return false;
/* Outer HMAC */
if(outlen >= mdlen) {
if(!hmac_sha512(secret, secretlen, data, sizeof data, out))
return false;
out += mdlen;
outlen -= mdlen;
} else {
if(!hmac_sha512(secret, secretlen, data, sizeof data, hash))
return false;
memcpy(out, hash, outlen);
out += outlen;
outlen = 0;
}
}
return true;
}

View file

@ -79,6 +79,13 @@ size_t cipher_keylength(const cipher_t *cipher) {
return cipher->cipher->key_len + cipher->cipher->iv_len;
}
size_t cipher_blocksize(const cipher_t *cipher) {
if(!cipher || !cipher->cipher)
return 1;
return cipher->cipher->block_size;
}
bool cipher_set_key(cipher_t *cipher, void *key, bool encrypt) {
bool result;

View file

@ -42,6 +42,7 @@ bool sigalrm = false;
extern char **g_argv;
extern bool use_logfile;
extern bool use_syslog;
/* Some functions the less gifted operating systems might lack... */
@ -61,12 +62,9 @@ static bool install_service(void) {
return false;
}
if(!strchr(program_name, '\\')) {
GetCurrentDirectory(sizeof command - 1, command + 1);
strncat(command, "\\", sizeof command - strlen(command));
}
strncat(command, program_name, sizeof command - strlen(command));
HMODULE module = GetModuleHandle(NULL);
GetModuleFileName(module, command + 1, sizeof command - 1);
command[sizeof command - 1] = 0;
strncat(command, "\"", sizeof command - strlen(command));
@ -189,6 +187,8 @@ bool init_service(void) {
Detach from current terminal
*/
bool detach(void) {
logmode_t logmode;
#ifndef HAVE_MINGW
signal(SIGPIPE, SIG_IGN);
signal(SIGUSR1, SIG_IGN);
@ -200,7 +200,7 @@ bool detach(void) {
if(do_detach) {
#ifndef HAVE_MINGW
if(daemon(0, 0)) {
if(daemon(1, 0)) {
logger(DEBUG_ALWAYS, LOG_ERR, "Couldn't detach from terminal: %s", strerror(errno));
return false;
}
@ -210,12 +210,17 @@ bool detach(void) {
#endif
}
openlogger(identname, use_logfile?LOGMODE_FILE:(do_detach?LOGMODE_SYSLOG:LOGMODE_STDERR));
if(use_logfile)
logmode = LOGMODE_FILE;
else if(use_syslog || do_detach)
logmode = LOGMODE_SYSLOG;
else
logmode = LOGMODE_STDERR;
openlogger(identname, logmode);
logger(DEBUG_ALWAYS, LOG_NOTICE, "tincd %s (%s %s) starting, debug level %d",
VERSION, BUILD_DATE, BUILD_TIME, debug_level);
BUILD_VERSION, BUILD_DATE, BUILD_TIME, debug_level);
return true;
}

View file

@ -41,6 +41,9 @@ static bool (*request_handlers[])(connection_t *, const char *) = {
add_subnet_h, del_subnet_h,
add_edge_h, del_edge_h,
key_changed_h, req_key_h, ans_key_h, tcppacket_h, control_h,
NULL, NULL, /* Not "real" requests (yet) */
sptps_tcppacket_h,
udp_info_h, mtu_info_h,
};
/* Request names */
@ -51,6 +54,7 @@ static char (*request_name[]) = {
"PING", "PONG",
"ADD_SUBNET", "DEL_SUBNET",
"ADD_EDGE", "DEL_EDGE", "KEY_CHANGED", "REQ_KEY", "ANS_KEY", "PACKET", "CONTROL",
"REQ_PUBKEY", "ANS_PUBKEY", "SPTPS_PACKET", "UDP_INFO", "MTU_INFO",
};
static splay_tree_t *past_request_tree;
@ -132,6 +136,7 @@ bool receive_request(connection_t *c, const char *request) {
if(!request_handlers[reqno](c, request)) {
/* Something went wrong. Probably scriptkiddies. Terminate. */
if(reqno != TERMREQ)
logger(DEBUG_ALWAYS, LOG_ERR, "Error while processing %s from %s (%s)", request_name[reqno], c->name, c->hostname);
return false;
}

View file

@ -26,7 +26,7 @@
/* Protocol version. Different major versions are incompatible. */
#define PROT_MAJOR 17
#define PROT_MINOR 4 /* Should not exceed 255! */
#define PROT_MINOR 7 /* Should not exceed 255! */
/* Silly Windows */
@ -48,7 +48,8 @@ typedef enum request_t {
/* Tinc 1.1 requests */
CONTROL,
REQ_PUBKEY, ANS_PUBKEY,
REQ_SPTPS,
SPTPS_PACKET,
UDP_INFO, MTU_INFO,
LAST /* Guardian for the highest request number */
} request_t;
@ -107,6 +108,9 @@ extern void send_key_changed(void);
extern bool send_req_key(struct node_t *);
extern bool send_ans_key(struct node_t *);
extern bool send_tcppacket(struct connection_t *, const struct vpn_packet_t *);
extern bool send_sptps_tcppacket(struct connection_t *, const char*, int);
extern bool send_udp_info(struct node_t *, struct node_t *);
extern bool send_mtu_info(struct node_t *, struct node_t *, int);
/* Request handlers */
@ -128,6 +132,9 @@ extern bool key_changed_h(struct connection_t *, const char *);
extern bool req_key_h(struct connection_t *, const char *);
extern bool ans_key_h(struct connection_t *, const char *);
extern bool tcppacket_h(struct connection_t *, const char *);
extern bool sptps_tcppacket_h(struct connection_t *, const char *);
extern bool control_h(struct connection_t *, const char *);
extern bool udp_info_h(struct connection_t *, const char *);
extern bool mtu_info_h(struct connection_t *, const char *);
#endif /* __TINC_PROTOCOL_H__ */

View file

@ -45,6 +45,8 @@
#include "utils.h"
#include "xalloc.h"
#include "ed25519/sha512.h"
ecdsa_t *invitation_key = NULL;
static bool send_proxyrequest(connection_t *c) {
@ -115,7 +117,7 @@ static bool send_proxyrequest(connection_t *c) {
i += 2;
c->tcplen += 22;
} else {
logger(DEBUG_ALWAYS, LOG_ERR, "Address family %hx not supported for SOCKS 5 proxies!", c->address.sa.sa_family);
logger(DEBUG_ALWAYS, LOG_ERR, "Address family %x not supported for SOCKS 5 proxies!", c->address.sa.sa_family);
return false;
}
if(i > len)
@ -211,17 +213,13 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const void *dat
return false;
// Recover the filename from the cookie and the key
digest_t *digest = digest_open_by_name("sha256", 18);
if(!digest)
abort();
char *fingerprint = ecdsa_get_base64_public_key(invitation_key);
char hashbuf[18 + strlen(fingerprint)];
char cookie[25];
char cookie[64];
memcpy(hashbuf, data, 18);
memcpy(hashbuf + 18, fingerprint, sizeof hashbuf - 18);
digest_create(digest, hashbuf, sizeof hashbuf, cookie);
sha512(hashbuf, sizeof hashbuf, cookie);
b64encode_urlsafe(cookie, cookie, 18);
digest_close(digest);
free(fingerprint);
char filename[PATH_MAX], usedname[PATH_MAX];
@ -388,7 +386,7 @@ bool id_h(connection_t *c, const char *request) {
/* Forbid version rollback for nodes whose Ed25519 key we know */
if(ecdsa_active(c->ecdsa) && c->protocol_minor < 2) {
if(ecdsa_active(c->ecdsa) && c->protocol_minor < 1) {
logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s (%s) tries to roll back protocol version to %d.%d",
c->name, c->hostname, c->protocol_major, c->protocol_minor);
return false;
@ -412,6 +410,9 @@ bool id_h(connection_t *c, const char *request) {
}
bool send_metakey(connection_t *c) {
#ifdef DISABLE_LEGACY
return false;
#else
if(!myself->connection->rsa) {
logger(DEBUG_CONNECTIONS, LOG_ERR, "Peer %s (%s) uses legacy protocol which we don't support", c->name, c->hostname);
return false;
@ -480,9 +481,13 @@ bool send_metakey(connection_t *c) {
c->status.encryptout = true;
return result;
#endif
}
bool metakey_h(connection_t *c, const char *request) {
#ifdef DISABLE_LEGACY
return false;
#else
if(!myself->connection->rsa)
return false;
@ -545,9 +550,13 @@ bool metakey_h(connection_t *c, const char *request) {
c->allow_request = CHALLENGE;
return send_challenge(c);
#endif
}
bool send_challenge(connection_t *c) {
#ifdef DISABLE_LEGACY
return false;
#else
const size_t len = rsa_size(c->rsa);
char buffer[len * 2 + 1];
@ -565,9 +574,13 @@ bool send_challenge(connection_t *c) {
/* Send the challenge */
return send_request(c, "%d %s", CHALLENGE, buffer);
#endif
}
bool challenge_h(connection_t *c, const char *request) {
#ifdef DISABLE_LEGACY
return false;
#else
if(!myself->connection->rsa)
return false;
@ -606,9 +619,13 @@ bool challenge_h(connection_t *c, const char *request) {
c->allow_request = CHAL_REPLY;
return send_request(c, "%d %s", CHAL_REPLY, buffer);
#endif
}
bool chal_reply_h(connection_t *c, const char *request) {
#ifdef DISABLE_LEGACY
return false;
#else
char hishash[MAX_STRING_SIZE];
if(sscanf(request, "%*d " MAX_STRING, hishash) != 1) {
@ -645,9 +662,13 @@ bool chal_reply_h(connection_t *c, const char *request) {
c->allow_request = ACK;
return send_ack(c);
#endif
}
static bool send_upgrade(connection_t *c) {
#ifdef DISABLE_LEGACY
return false;
#else
/* Special case when protocol_minor is 1: the other end is Ed25519 capable,
* but doesn't know our key yet. So send it now. */
@ -659,6 +680,7 @@ static bool send_upgrade(connection_t *c) {
bool result = send_request(c, "%d %s", ACK, pubkey);
free(pubkey);
return result;
#endif
}
bool send_ack(connection_t *c) {
@ -758,6 +780,8 @@ static bool upgrade_h(connection_t *c, const char *request) {
logger(DEBUG_ALWAYS, LOG_INFO, "Got Ed25519 public key from %s (%s), upgrading!", c->name, c->hostname);
append_config_file(c->name, "Ed25519PublicKey", pubkey);
c->allow_request = TERMREQ;
if(c->outgoing)
c->outgoing->timeout = 0;
return send_termreq(c);
}

View file

@ -37,19 +37,26 @@
bool send_add_edge(connection_t *c, const edge_t *e) {
bool x;
char *address, *port;
char *local_address, *local_port;
sockaddr2str(&e->address, &address, &port);
if(e->local_address.sa.sa_family) {
char *local_address, *local_port;
sockaddr2str(&e->local_address, &local_address, &local_port);
x = send_request(c, "%d %x %s %s %s %s %x %d %s %s", ADD_EDGE, rand(),
e->from->name, e->to->name, address, port,
e->options, e->weight, local_address, local_port);
free(local_address);
free(local_port);
} else {
x = send_request(c, "%d %x %s %s %s %s %x %d", ADD_EDGE, rand(),
e->from->name, e->to->name, address, port,
e->options, e->weight);
}
free(address);
free(port);
free(local_address);
free(local_port);
return x;
}
@ -61,9 +68,9 @@ bool add_edge_h(connection_t *c, const char *request) {
char to_name[MAX_STRING_SIZE];
char to_address[MAX_STRING_SIZE];
char to_port[MAX_STRING_SIZE];
char address_local[MAX_STRING_SIZE] = "unknown";
char port_local[MAX_STRING_SIZE] = "unknown";
sockaddr_t address, local_address;
char address_local[MAX_STRING_SIZE];
char port_local[MAX_STRING_SIZE];
sockaddr_t address, local_address = {{0}};
uint32_t options;
int weight;
@ -117,6 +124,7 @@ bool add_edge_h(connection_t *c, const char *request) {
/* Convert addresses */
address = str2sockaddr(to_address, to_port);
if(parameter_count >= 8)
local_address = str2sockaddr(address_local, port_local);
/* Check if edge already exists */
@ -124,20 +132,63 @@ bool add_edge_h(connection_t *c, const char *request) {
e = lookup_edge(from, to);
if(e) {
if(e->weight != weight || e->options != options || sockaddrcmp(&e->address, &address) || sockaddrcmp(&e->local_address, &local_address)) {
if(e->weight != weight || e->options != options || sockaddrcmp(&e->address, &address)) {
if(from == myself) {
logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself which does not match existing entry",
"ADD_EDGE", c->name, c->hostname);
send_add_edge(c, e);
sockaddrfree(&local_address);
return true;
} else {
logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) which does not match existing entry",
"ADD_EDGE", c->name, c->hostname);
edge_del(e);
graph();
e->options = options;
if(sockaddrcmp(&e->address, &address)) {
sockaddrfree(&e->address);
e->address = address;
}
} else
if(e->weight != weight) {
splay_node_t *node = splay_unlink(edge_weight_tree, e);
e->weight = weight;
splay_insert_node(edge_weight_tree, node);
}
goto done;
}
} else if(sockaddrcmp(&e->local_address, &local_address)) {
if(from == myself) {
if(e->local_address.sa.sa_family && local_address.sa.sa_family) {
// Someone has the wrong local address for ourself. Correct then.
logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself which does not match existing entry",
"ADD_EDGE", c->name, c->hostname);
send_add_edge(c, e);
sockaddrfree(&local_address);
return true;
}
// Otherwise, just ignore it.
sockaddrfree(&local_address);
return true;
} else if(local_address.sa.sa_family && local_address.sa.sa_family != AF_UNKNOWN) {
// We learned a new local address for this edge.
// local_address.sa.sa_family will be 0 if we got it from older tinc versions
// local_address.sa.sa_family will be 255 (AF_UNKNOWN) if we got it from newer versions
// but for edge which does not have local_address
sockaddrfree(&e->local_address);
e->local_address = local_address;
// Tell others about it.
if(!tunnelserver)
forward_request(c, request);
return true;
} else {
sockaddrfree(&local_address);
return true;
}
} else {
sockaddrfree(&local_address);
return true;
}
} else if(from == myself) {
logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself which does not exist",
"ADD_EDGE", c->name, c->hostname);
@ -147,6 +198,7 @@ bool add_edge_h(connection_t *c, const char *request) {
e->to = to;
send_del_edge(c, e);
free_edge(e);
sockaddrfree(&local_address);
return true;
}
@ -159,6 +211,7 @@ bool add_edge_h(connection_t *c, const char *request) {
e->weight = weight;
edge_add(e);
done:
/* Tell the rest about the new edge */
if(!tunnelserver)

View file

@ -36,6 +36,7 @@
static bool mykeyused = false;
void send_key_changed(void) {
#ifndef DISABLE_LEGACY
send_request(everyone, "%d %x %s", KEY_CHANGED, rand(), myself->name);
/* Immediately send new keys to directly connected nodes to keep UDP mappings alive */
@ -43,6 +44,7 @@ void send_key_changed(void) {
for list_each(connection_t, c, connection_list)
if(c->edge && c->node && c->node->status.reachable && !c->node->status.sptps)
send_ans_key(c->node);
#endif
/* Force key exchange for connections using SPTPS */
@ -87,9 +89,13 @@ bool key_changed_h(connection_t *c, const char *request) {
return true;
}
static bool send_sptps_data_myself(void *handle, uint8_t type, const void *data, size_t len) {
return send_sptps_data(handle, myself, type, data, len);
}
static bool send_initial_sptps_data(void *handle, uint8_t type, const void *data, size_t len) {
node_t *to = handle;
to->sptps.send_data = send_sptps_data;
to->sptps.send_data = send_sptps_data_myself;
char buf[len * 4 / 3 + 5];
b64encode(data, buf, len);
return send_request(to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, to->name, REQ_KEY, buf);
@ -103,9 +109,6 @@ bool send_req_key(node_t *to) {
return true;
}
if(to->sptps.label)
logger(DEBUG_ALWAYS, LOG_DEBUG, "send_req_key(%s) called while sptps->label != NULL!", to->name);
char label[25 + strlen(myself->name) + strlen(to->name)];
snprintf(label, sizeof label, "tinc UDP key expansion %s %s", myself->name, to->name);
sptps_stop(&to->sptps);
@ -121,7 +124,52 @@ bool send_req_key(node_t *to) {
/* REQ_KEY is overloaded to allow arbitrary requests to be routed between two nodes. */
static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, int reqno) {
static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, node_t *to, int reqno) {
/* If this is a SPTPS packet, see if sending UDP info helps.
Note that we only do this if we're the destination or the static relay;
otherwise every hop would initiate its own UDP info message, resulting in elevated chatter. */
if((reqno == REQ_KEY || reqno == SPTPS_PACKET) && to->via == myself)
send_udp_info(myself, from);
if(reqno == SPTPS_PACKET) {
/* This is a SPTPS data packet. */
char buf[MAX_STRING_SIZE];
int len;
if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) {
logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s) to %s (%s): %s", "SPTPS_PACKET", from->name, from->hostname, to->name, to->hostname, "invalid SPTPS data");
return true;
}
if(to != myself) {
/* We don't just forward the request, because we want to use UDP if it's available. */
send_sptps_data(to, from, 0, buf, len);
try_tx(to, true);
} else {
/* The packet is for us */
if(!sptps_receive_data(&from->sptps, buf, len)) {
/* Uh-oh. It might be that the tunnel is stuck in some corrupted state,
so let's restart SPTPS in case that helps. But don't do that too often
to prevent storms. */
if(from->last_req_key < now.tv_sec - 10) {
logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname);
send_req_key(from);
}
return true;
}
send_mtu_info(myself, from, MTU);
}
return true;
}
/* Requests that are not SPTPS data packets are forwarded as-is. */
if (to != myself)
return send_request(to->nexthop->connection, "%s", request);
/* The request is for us */
switch(reqno) {
case REQ_PUBKEY: {
if(!node_read_ecdsa_public_key(from)) {
@ -176,24 +224,9 @@ static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, in
from->status.validkey = false;
from->status.waitingforkey = true;
from->last_req_key = now.tv_sec;
sptps_start(&from->sptps, from, false, true, myself->connection->ecdsa, from->ecdsa, label, sizeof label, send_sptps_data, receive_sptps_record);
sptps_receive_data(&from->sptps, buf, len);
return true;
}
case REQ_SPTPS: {
if(!from->status.validkey) {
logger(DEBUG_PROTOCOL, LOG_ERR, "Got REQ_SPTPS from %s (%s) but we don't have a valid key yet", from->name, from->hostname);
return true;
}
char buf[MAX_STRING_SIZE];
int len;
if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) {
logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_SPTPS", from->name, from->hostname, "invalid SPTPS data");
return true;
}
sptps_start(&from->sptps, from, false, true, myself->connection->ecdsa, from->ecdsa, label, sizeof label, send_sptps_data_myself, receive_sptps_record);
sptps_receive_data(&from->sptps, buf, len);
send_mtu_info(myself, from, MTU);
return true;
}
@ -241,7 +274,7 @@ bool req_key_h(connection_t *c, const char *request) {
if(to == myself) { /* Yes */
/* Is this an extended REQ_KEY message? */
if(experimental && reqno)
return req_key_ext_h(c, request, from, reqno);
return req_key_ext_h(c, request, from, to, reqno);
/* No, just send our key back */
send_ans_key(from);
@ -255,7 +288,10 @@ bool req_key_h(connection_t *c, const char *request) {
return true;
}
/* TODO: forwarding SPTPS packets in this way is inefficient because we send them over TCP without checking for UDP connectivity */
/* Is this an extended REQ_KEY message? */
if(experimental && reqno)
return req_key_ext_h(c, request, from, to, reqno);
send_request(to->nexthop->connection, "%s", request);
}
@ -266,6 +302,9 @@ bool send_ans_key(node_t *to) {
if(to->status.sptps)
abort();
#ifdef DISABLE_LEGACY
return false;
#else
size_t keylen = myself->incipher ? cipher_keylength(myself->incipher) : 1;
char key[keylen * 2 + 1];
@ -300,12 +339,15 @@ bool send_ans_key(node_t *to) {
to->received = 0;
if(replaywin) memset(to->late, 0, replaywin);
to->status.validkey_in = true;
return send_request(to->nexthop->connection, "%d %s %s %s %d %d %d %d", ANS_KEY,
myself->name, to->name, key,
cipher_get_nid(to->incipher),
digest_get_nid(to->indigest),
(int)digest_length(to->indigest),
to->incompression);
#endif
}
bool ans_key_h(connection_t *c, const char *request) {
@ -358,7 +400,7 @@ bool ans_key_h(connection_t *c, const char *request) {
return true;
}
if(!*address && from->address.sa.sa_family != AF_UNSPEC) {
if(!*address && from->address.sa.sa_family != AF_UNSPEC && to->minmtu) {
char *address, *port;
logger(DEBUG_PROTOCOL, LOG_DEBUG, "Appending reflexive UDP address to ANS_KEY from %s to %s", from->name, to->name);
sockaddr2str(&from->address, &address, &port);
@ -371,10 +413,12 @@ bool ans_key_h(connection_t *c, const char *request) {
return send_request(to->nexthop->connection, "%s", request);
}
#ifndef DISABLE_LEGACY
/* Don't use key material until every check has passed. */
cipher_close(from->outcipher);
digest_close(from->outdigest);
from->status.validkey = false;
#endif
if (!from->status.sptps) from->status.validkey = false;
if(compression < 0 || compression > 11) {
logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
@ -388,9 +432,18 @@ bool ans_key_h(connection_t *c, const char *request) {
if(from->status.sptps) {
char buf[strlen(key)];
int len = b64decode(key, buf, strlen(key));
if(!len || !sptps_receive_data(&from->sptps, buf, len))
logger(DEBUG_ALWAYS, LOG_ERR, "Error processing SPTPS data from %s (%s)", from->name, from->hostname);
if(!len || !sptps_receive_data(&from->sptps, buf, len)) {
/* Uh-oh. It might be that the tunnel is stuck in some corrupted state,
so let's restart SPTPS in case that helps. But don't do that too often
to prevent storms.
Note that simply relying on handshake timeout is not enough, because
that doesn't apply to key regeneration. */
if(from->last_req_key < now.tv_sec - 10) {
logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode handshake TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname);
send_req_key(from);
}
return true;
}
if(from->status.validkey) {
if(*address && *port) {
@ -398,16 +451,17 @@ bool ans_key_h(connection_t *c, const char *request) {
sockaddr_t sa = str2sockaddr(address, port);
update_node_udp(from, &sa);
}
/* Don't send probes if we can't send UDP packets directly to that node.
TODO: the indirect (via) condition can change at any time as edges are added and removed, so this should probably be moved to graph.c. */
if((from->via == myself || from->via == from) && from->options & OPTION_PMTU_DISCOVERY && !(from->options & OPTION_TCPONLY))
send_mtu_probe(from);
}
send_mtu_info(myself, from, MTU);
return true;
}
#ifdef DISABLE_LEGACY
logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses legacy protocol!", from->name, from->hostname);
return false;
#else
/* Check and lookup cipher and digest algorithms */
if(cipher) {
@ -458,8 +512,6 @@ bool ans_key_h(connection_t *c, const char *request) {
update_node_udp(from, &sa);
}
if(from->options & OPTION_PMTU_DISCOVERY && !(from->options & OPTION_TCPONLY))
send_mtu_probe(from);
return true;
#endif
}

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