upstream: 1.18

This commit is contained in:
lagertonne 2022-04-22 20:24:15 +02:00
parent 8e468ffc54
commit ff84fef381
88 changed files with 6525 additions and 26617 deletions

View file

@ -190,10 +190,6 @@ if MINGW
tincd_SOURCES += mingw/device.c mingw/common.h
endif
if CYGWIN
tincd_SOURCES += cygwin/device.c
endif
if UML
tincd_SOURCES += uml_device.c
endif

View file

@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.16.1 from Makefile.am.
# Makefile.in generated by automake 1.16.3 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -114,17 +114,16 @@ EXTRA_PROGRAMS = sptps_test$(EXEEXT) sptps_keypair$(EXEEXT) \
@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 = \
@UML_TRUE@am__append_11 = uml_device.c
@VDE_TRUE@am__append_12 = vde_device.c
@OPENSSL_TRUE@am__append_13 = \
@OPENSSL_TRUE@ openssl/cipher.c \
@OPENSSL_TRUE@ openssl/crypto.c \
@OPENSSL_TRUE@ openssl/digest.c openssl/digest.h \
@OPENSSL_TRUE@ openssl/prf.c \
@OPENSSL_TRUE@ openssl/rsa.c
@OPENSSL_TRUE@am__append_15 = \
@OPENSSL_TRUE@am__append_14 = \
@OPENSSL_TRUE@ openssl/cipher.c \
@OPENSSL_TRUE@ openssl/crypto.c \
@OPENSSL_TRUE@ openssl/digest.c openssl/digest.h \
@ -132,27 +131,27 @@ EXTRA_PROGRAMS = sptps_test$(EXEEXT) sptps_keypair$(EXEEXT) \
@OPENSSL_TRUE@ openssl/rsa.c \
@OPENSSL_TRUE@ openssl/rsagen.c
@OPENSSL_TRUE@am__append_16 = \
@OPENSSL_TRUE@am__append_15 = \
@OPENSSL_TRUE@ openssl/crypto.c \
@OPENSSL_TRUE@ openssl/digest.c openssl/digest.h \
@OPENSSL_TRUE@ openssl/prf.c
@OPENSSL_TRUE@am__append_17 = \
@OPENSSL_TRUE@am__append_16 = \
@OPENSSL_TRUE@ openssl/crypto.c
@OPENSSL_TRUE@am__append_18 = \
@OPENSSL_TRUE@am__append_17 = \
@OPENSSL_TRUE@ openssl/crypto.c \
@OPENSSL_TRUE@ openssl/digest.c openssl/digest.h \
@OPENSSL_TRUE@ openssl/prf.c
@GCRYPT_TRUE@@OPENSSL_FALSE@am__append_19 = \
@GCRYPT_TRUE@@OPENSSL_FALSE@am__append_18 = \
@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@am__append_20 = \
@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 \
@ -160,20 +159,24 @@ EXTRA_PROGRAMS = sptps_test$(EXEEXT) sptps_keypair$(EXEEXT) \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/rsa.c \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/rsagen.c
@GCRYPT_TRUE@@OPENSSL_FALSE@am__append_21 = \
@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@am__append_22 = \
@GCRYPT_TRUE@@OPENSSL_FALSE@am__append_21 = \
@GCRYPT_TRUE@@OPENSSL_FALSE@ openssl/crypto.c
@GCRYPT_TRUE@@OPENSSL_FALSE@am__append_23 = \
@GCRYPT_TRUE@@OPENSSL_FALSE@am__append_22 = \
@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_23 = \
@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/crypto.c \
@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/prf.c
@GCRYPT_FALSE@@OPENSSL_FALSE@am__append_24 = \
@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/crypto.c \
@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/prf.c
@ -183,18 +186,14 @@ EXTRA_PROGRAMS = sptps_test$(EXEEXT) sptps_keypair$(EXEEXT) \
@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@am__append_27 = \
@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
@MINIUPNPC_TRUE@am__append_28 = upnp.h upnp.c
@TUNEMU_TRUE@am__append_29 = -lpcap
subdir = src
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
@ -362,8 +361,8 @@ am__tincd_SOURCES_DIST = address_cache.c address_cache.h autoconnect.c \
chacha-poly1305/chacha-poly1305.h chacha-poly1305/poly1305.c \
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 \
solaris/device.c mingw/device.c mingw/common.h 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 \
@ -373,19 +372,18 @@ am__tincd_SOURCES_DIST = address_cache.c address_cache.h autoconnect.c \
@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) \
@UML_TRUE@am__objects_18 = uml_device.$(OBJEXT)
@VDE_TRUE@am__objects_19 = vde_device.$(OBJEXT)
@OPENSSL_TRUE@am__objects_20 = openssl/cipher.$(OBJEXT) \
@OPENSSL_TRUE@ openssl/crypto.$(OBJEXT) \
@OPENSSL_TRUE@ openssl/digest.$(OBJEXT) openssl/prf.$(OBJEXT) \
@OPENSSL_TRUE@ openssl/rsa.$(OBJEXT)
@GCRYPT_TRUE@@OPENSSL_FALSE@am__objects_22 = gcrypt/cipher.$(OBJEXT) \
@GCRYPT_TRUE@@OPENSSL_FALSE@am__objects_21 = 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)
@MINIUPNPC_TRUE@am__objects_22 = upnp.$(OBJEXT)
am_tincd_OBJECTS = address_cache.$(OBJEXT) autoconnect.$(OBJEXT) \
buffer.$(OBJEXT) conf.$(OBJEXT) connection.$(OBJEXT) \
control.$(OBJEXT) dropin.$(OBJEXT) dummy_device.$(OBJEXT) \
@ -405,8 +403,7 @@ am_tincd_OBJECTS = address_cache.$(OBJEXT) autoconnect.$(OBJEXT) \
$(am__objects_2) $(am__objects_13) $(am__objects_14) \
$(am__objects_15) $(am__objects_16) $(am__objects_17) \
$(am__objects_18) $(am__objects_19) $(am__objects_20) \
$(am__objects_21) $(am__objects_22) $(am__objects_9) \
$(am__objects_23)
$(am__objects_21) $(am__objects_9) $(am__objects_22)
tincd_OBJECTS = $(am_tincd_OBJECTS)
@MINIUPNPC_TRUE@tincd_DEPENDENCIES = $(am__DEPENDENCIES_1)
tincd_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(tincd_LDFLAGS) \
@ -458,21 +455,20 @@ am__depfiles_remade = ./$(DEPDIR)/address_cache.Po \
chacha-poly1305/$(DEPDIR)/chacha-poly1305.Po \
chacha-poly1305/$(DEPDIR)/chacha.Po \
chacha-poly1305/$(DEPDIR)/poly1305.Po \
cygwin/$(DEPDIR)/device.Po ed25519/$(DEPDIR)/ecdh.Po \
ed25519/$(DEPDIR)/ecdsa.Po ed25519/$(DEPDIR)/ecdsagen.Po \
ed25519/$(DEPDIR)/fe.Po ed25519/$(DEPDIR)/ge.Po \
ed25519/$(DEPDIR)/key_exchange.Po ed25519/$(DEPDIR)/keypair.Po \
ed25519/$(DEPDIR)/sc.Po ed25519/$(DEPDIR)/sha512.Po \
ed25519/$(DEPDIR)/sign.Po ed25519/$(DEPDIR)/verify.Po \
gcrypt/$(DEPDIR)/cipher.Po gcrypt/$(DEPDIR)/crypto.Po \
gcrypt/$(DEPDIR)/digest.Po gcrypt/$(DEPDIR)/prf.Po \
gcrypt/$(DEPDIR)/rsa.Po gcrypt/$(DEPDIR)/rsagen.Po \
linux/$(DEPDIR)/device.Po mingw/$(DEPDIR)/device.Po \
nolegacy/$(DEPDIR)/crypto.Po nolegacy/$(DEPDIR)/prf.Po \
openssl/$(DEPDIR)/cipher.Po openssl/$(DEPDIR)/crypto.Po \
openssl/$(DEPDIR)/digest.Po openssl/$(DEPDIR)/prf.Po \
openssl/$(DEPDIR)/rsa.Po openssl/$(DEPDIR)/rsagen.Po \
solaris/$(DEPDIR)/device.Po
ed25519/$(DEPDIR)/ecdh.Po ed25519/$(DEPDIR)/ecdsa.Po \
ed25519/$(DEPDIR)/ecdsagen.Po ed25519/$(DEPDIR)/fe.Po \
ed25519/$(DEPDIR)/ge.Po ed25519/$(DEPDIR)/key_exchange.Po \
ed25519/$(DEPDIR)/keypair.Po ed25519/$(DEPDIR)/sc.Po \
ed25519/$(DEPDIR)/sha512.Po ed25519/$(DEPDIR)/sign.Po \
ed25519/$(DEPDIR)/verify.Po gcrypt/$(DEPDIR)/cipher.Po \
gcrypt/$(DEPDIR)/crypto.Po gcrypt/$(DEPDIR)/digest.Po \
gcrypt/$(DEPDIR)/prf.Po gcrypt/$(DEPDIR)/rsa.Po \
gcrypt/$(DEPDIR)/rsagen.Po linux/$(DEPDIR)/device.Po \
mingw/$(DEPDIR)/device.Po nolegacy/$(DEPDIR)/crypto.Po \
nolegacy/$(DEPDIR)/prf.Po openssl/$(DEPDIR)/cipher.Po \
openssl/$(DEPDIR)/crypto.Po openssl/$(DEPDIR)/digest.Po \
openssl/$(DEPDIR)/prf.Po openssl/$(DEPDIR)/rsa.Po \
openssl/$(DEPDIR)/rsagen.Po solaris/$(DEPDIR)/device.Po
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@ -555,7 +551,7 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LCOV = @LCOV@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@ -lm $(CODE_COVERAGE_LIBS) $(am__append_30)
LIBS = @LIBS@ -lm $(CODE_COVERAGE_LIBS) $(am__append_29)
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MINIUPNPC_LIBS = @MINIUPNPC_LIBS@
@ -665,28 +661,27 @@ tincd_SOURCES = address_cache.c address_cache.h autoconnect.c \
$(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)
$(am__append_18) $(am__append_23) $(am__append_28)
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/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)
$(chacha_poly1305_SOURCES) $(am__append_3) $(am__append_14) \
$(am__append_19) $(am__append_24)
sptps_test_SOURCES = logger.c logger.h sptps.c sptps.h sptps_test.c \
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)
$(am__append_15) $(am__append_20) $(am__append_25)
sptps_keypair_SOURCES = sptps_keypair.c utils.c utils.h \
ed25519/ecdsagen.c $(ed25519_SOURCES) $(am__append_5) \
$(am__append_17) $(am__append_22) $(am__append_27)
$(am__append_16) $(am__append_21) $(am__append_26)
sptps_speed_SOURCES = logger.c logger.h sptps.c sptps.h sptps_speed.c \
utils.c utils.h ed25519/ecdh.c ed25519/ecdsa.c \
ed25519/ecdsagen.c $(ed25519_SOURCES) \
$(chacha_poly1305_SOURCES) $(am__append_18) $(am__append_23) \
$(am__append_28)
$(chacha_poly1305_SOURCES) $(am__append_17) $(am__append_22) \
$(am__append_27)
@MINIUPNPC_TRUE@tincd_LDADD = $(MINIUPNPC_LIBS)
@MINIUPNPC_TRUE@tincd_LDFLAGS = -pthread
tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS)
@ -924,14 +919,6 @@ mingw/$(DEPDIR)/$(am__dirstamp):
@: > mingw/$(DEPDIR)/$(am__dirstamp)
mingw/device.$(OBJEXT): mingw/$(am__dirstamp) \
mingw/$(DEPDIR)/$(am__dirstamp)
cygwin/$(am__dirstamp):
@$(MKDIR_P) cygwin
@: > cygwin/$(am__dirstamp)
cygwin/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) cygwin/$(DEPDIR)
@: > cygwin/$(DEPDIR)/$(am__dirstamp)
cygwin/device.$(OBJEXT): cygwin/$(am__dirstamp) \
cygwin/$(DEPDIR)/$(am__dirstamp)
tincd$(EXEEXT): $(tincd_OBJECTS) $(tincd_DEPENDENCIES) $(EXTRA_tincd_DEPENDENCIES)
@rm -f tincd$(EXEEXT)
@ -941,7 +928,6 @@ mostlyclean-compile:
-rm -f *.$(OBJEXT)
-rm -f bsd/*.$(OBJEXT)
-rm -f chacha-poly1305/*.$(OBJEXT)
-rm -f cygwin/*.$(OBJEXT)
-rm -f ed25519/*.$(OBJEXT)
-rm -f gcrypt/*.$(OBJEXT)
-rm -f linux/*.$(OBJEXT)
@ -1013,7 +999,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/chacha-poly1305.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/chacha.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/poly1305.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@cygwin/$(DEPDIR)/device.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdh.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdsa.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdsagen.Po@am__quote@ # am--include-marker
@ -1189,8 +1174,6 @@ distclean-generic:
-rm -f bsd/$(am__dirstamp)
-rm -f chacha-poly1305/$(DEPDIR)/$(am__dirstamp)
-rm -f chacha-poly1305/$(am__dirstamp)
-rm -f cygwin/$(DEPDIR)/$(am__dirstamp)
-rm -f cygwin/$(am__dirstamp)
-rm -f ed25519/$(DEPDIR)/$(am__dirstamp)
-rm -f ed25519/$(am__dirstamp)
-rm -f gcrypt/$(DEPDIR)/$(am__dirstamp)
@ -1275,7 +1258,6 @@ distclean: distclean-am
-rm -f chacha-poly1305/$(DEPDIR)/chacha-poly1305.Po
-rm -f chacha-poly1305/$(DEPDIR)/chacha.Po
-rm -f chacha-poly1305/$(DEPDIR)/poly1305.Po
-rm -f cygwin/$(DEPDIR)/device.Po
-rm -f ed25519/$(DEPDIR)/ecdh.Po
-rm -f ed25519/$(DEPDIR)/ecdsa.Po
-rm -f ed25519/$(DEPDIR)/ecdsagen.Po
@ -1409,7 +1391,6 @@ maintainer-clean: maintainer-clean-am
-rm -f chacha-poly1305/$(DEPDIR)/chacha-poly1305.Po
-rm -f chacha-poly1305/$(DEPDIR)/chacha.Po
-rm -f chacha-poly1305/$(DEPDIR)/poly1305.Po
-rm -f cygwin/$(DEPDIR)/device.Po
-rm -f ed25519/$(DEPDIR)/ecdh.Po
-rm -f ed25519/$(DEPDIR)/ecdsa.Po
-rm -f ed25519/$(DEPDIR)/ecdsagen.Po

View file

@ -151,7 +151,7 @@ const sockaddr_t *get_recent_address(address_cache_t *cache) {
cache->cfg = lookup_config(cache->config_tree, "Address");
}
while(cache->cfg && !cache->ai) {
while(cache->cfg && !cache->aip) {
char *address, *port;
get_config_string(cache->cfg, &address);
@ -167,6 +167,10 @@ const sockaddr_t *get_recent_address(address_cache_t *cache) {
}
}
if(cache->ai) {
free_known_addresses(cache->ai);
}
cache->aip = cache->ai = str2addrinfo(address, port, SOCK_STREAM);
if(cache->ai) {

View file

@ -186,10 +186,9 @@ void do_autoconnect() {
drop_superfluous_outgoing_connection();
}
/* Drop pending outgoing connections from the outgoing list. */
drop_superfluous_pending_connections();
/* Check if there are unreachable nodes that we should try to connect to. */
connect_to_unreachable();
/* Drop pending outgoing connections from the outgoing list. */
drop_superfluous_pending_connections();
}

View file

@ -1,7 +1,7 @@
/*
device.c -- Interaction BSD tun/tap device
Copyright (C) 2001-2005 Ivo Timmermans,
2001-2017 Guus Sliepen <guus@tinc-vpn.org>
2001-2021 Guus Sliepen <guus@tinc-vpn.org>
2009 Grzegorz Dymarek <gregd72002@googlemail.com>
This program is free software; you can redistribute it and/or modify
@ -40,8 +40,13 @@
#include <net/if_utun.h>
#endif
#if defined(HAVE_FREEBSD) || defined(HAVE_DRAGONFLY)
#define DEFAULT_TUN_DEVICE "/dev/tun" // Use the autoclone device
#define DEFAULT_TAP_DEVICE "/dev/tap"
#else
#define DEFAULT_TUN_DEVICE "/dev/tun0"
#define DEFAULT_TAP_DEVICE "/dev/tap0"
#endif
typedef enum device_type {
DEVICE_TYPE_TUN,

View file

@ -4,7 +4,7 @@
1998-2005 Ivo Timmermans
2000 Cris van Pelt
2010-2011 Julien Muchembled <jm@jmuchemb.eu>
2000-2015 Guus Sliepen <guus@tinc-vpn.org>
2000-2021 Guus Sliepen <guus@tinc-vpn.org>
2013 Florent Clairambault <florent@clairambault.fr>
This program is free software; you can redistribute it and/or modify
@ -206,20 +206,14 @@ bool get_config_subnet(const config_t *cfg, subnet_t **result) {
return false;
}
/* Teach newbies what subnets are... */
if(((subnet.type == SUBNET_IPV4)
&& !maskcheck(&subnet.net.ipv4.address, subnet.net.ipv4.prefixlength, sizeof(subnet.net.ipv4.address)))
|| ((subnet.type == SUBNET_IPV6)
&& !maskcheck(&subnet.net.ipv6.address, subnet.net.ipv6.prefixlength, sizeof(subnet.net.ipv6.address)))) {
logger(DEBUG_ALWAYS, LOG_ERR, "Network address and prefix length do not match for configuration variable %s in %s line %d",
cfg->variable, cfg->file, cfg->line);
return false;
if(subnetcheck(subnet)) {
*(*result = new_subnet()) = subnet;
return true;
}
*(*result = new_subnet()) = subnet;
return true;
logger(DEBUG_ALWAYS, LOG_ERR, "Network address and prefix length do not match for configuration variable %s in %s line %d",
cfg->variable, cfg->file, cfg->line);
return false;
}
/*

View file

@ -1,278 +0,0 @@
/*
device.c -- Interaction with Windows tap driver in a Cygwin environment
Copyright (C) 2002-2005 Ivo Timmermans,
2002-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 "../net.h"
#include <w32api/windows.h>
#include <w32api/winioctl.h>
#include "../conf.h"
#include "../device.h"
#include "../logger.h"
#include "../names.h"
#include "../route.h"
#include "../utils.h"
#include "../xalloc.h"
#include "../mingw/common.h"
int device_fd = -1;
static HANDLE device_handle = INVALID_HANDLE_VALUE;
char *device = NULL;
char *iface = NULL;
static const char *device_info = "Windows tap device";
static pid_t reader_pid;
static int sp[2];
static bool setup_device(void) {
HKEY key, key2;
int i, err;
char regpath[1024];
char adapterid[1024];
char adaptername[1024];
char tapname[1024];
char gelukt = 0;
long len;
bool found = false;
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)) {
logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read registry: %s", winerror(GetLastError()));
return false;
}
for(i = 0; ; i++) {
len = sizeof(adapterid);
if(RegEnumKeyEx(key, i, adapterid, &len, 0, 0, 0, NULL)) {
break;
}
/* Find out more about this adapter */
snprintf(regpath, sizeof(regpath), "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, adapterid);
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2)) {
continue;
}
len = sizeof(adaptername);
err = RegQueryValueEx(key2, "Name", 0, 0, adaptername, &len);
RegCloseKey(key2);
if(err) {
continue;
}
if(device) {
if(!strcmp(device, adapterid)) {
found = true;
break;
} else {
continue;
}
}
if(iface) {
if(!strcmp(iface, adaptername)) {
found = true;
break;
} else {
continue;
}
}
snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, adapterid);
device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0);
if(device_handle != INVALID_HANDLE_VALUE) {
CloseHandle(device_handle);
found = true;
break;
}
}
RegCloseKey(key);
if(!found) {
logger(DEBUG_ALWAYS, LOG_ERR, "No Windows tap device found!");
return false;
}
if(!device) {
device = xstrdup(adapterid);
}
if(!iface) {
iface = xstrdup(adaptername);
}
snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, device);
/* Now we are going to open this device twice: once for reading and once for writing.
We do this because apparently it isn't possible to check for activity in the select() loop.
Furthermore I don't really know how to do it the "Windows" way. */
if(socketpair(AF_UNIX, SOCK_DGRAM, PF_UNIX, sp)) {
logger(DEBUG_ALWAYS, LOG_DEBUG, "System call `%s' failed: %s", "socketpair", strerror(errno));
return false;
}
/* The parent opens the tap device for writing. */
device_handle = CreateFile(tapname, GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0);
if(device_handle == INVALID_HANDLE_VALUE) {
logger(DEBUG_ALWAYS, LOG_ERR, "Could not open Windows tap device %s (%s) for writing: %s", device, iface, winerror(GetLastError()));
return false;
}
device_fd = sp[0];
/* 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)) {
logger(DEBUG_ALWAYS, LOG_ERR, "Could not get MAC address from Windows tap device %s (%s): %s", device, iface, winerror(GetLastError()));
return false;
}
if(routing_mode == RMODE_ROUTER) {
overwrite_mac = 1;
}
/* Now we start the child */
reader_pid = fork();
if(reader_pid == -1) {
logger(DEBUG_ALWAYS, LOG_DEBUG, "System call `%s' failed: %s", "fork", strerror(errno));
return false;
}
if(!reader_pid) {
/* The child opens the tap device for reading, blocking.
It passes everything it reads to the socket. */
char buf[MTU];
long inlen;
CloseHandle(device_handle);
device_handle = CreateFile(tapname, GENERIC_READ, FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0);
if(device_handle == INVALID_HANDLE_VALUE) {
logger(DEBUG_ALWAYS, LOG_ERR, "Could not open Windows tap device %s (%s) for reading: %s", device, iface, winerror(GetLastError()));
buf[0] = 0;
write(sp[1], buf, 1);
exit(1);
}
logger(DEBUG_ALWAYS, LOG_DEBUG, "Tap reader forked and running.");
/* Notify success */
buf[0] = 1;
write(sp[1], buf, 1);
/* Pass packets */
for(;;) {
ReadFile(device_handle, buf, MTU, &inlen, NULL);
write(sp[1], buf, inlen);
}
}
read(device_fd, &gelukt, 1);
if(gelukt != 1) {
logger(DEBUG_ALWAYS, LOG_DEBUG, "Tap reader failed!");
return false;
}
logger(DEBUG_ALWAYS, LOG_INFO, "%s (%s) is a %s", device, iface, device_info);
return true;
}
static void close_device(void) {
close(sp[0]);
close(sp[1]);
CloseHandle(device_handle);
device_handle = INVALID_HANDLE_VALUE;
kill(reader_pid, SIGKILL);
free(device);
device = NULL;
free(iface);
iface = NULL;
device_info = NULL;
}
static bool read_packet(vpn_packet_t *packet) {
int inlen;
if((inlen = read(sp[0], DATA(packet), MTU)) <= 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info,
device, strerror(errno));
return false;
}
packet->len = inlen;
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len,
device_info);
return true;
}
static bool write_packet(vpn_packet_t *packet) {
long outlen;
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s",
packet->len, device_info);
if(!WriteFile(device_handle, DATA(packet), packet->len, &outlen, NULL)) {
logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, device, winerror(GetLastError()));
return false;
}
return true;
}
const devops_t os_devops = {
.setup = setup_device,
.close = close_device,
.read = read_packet,
.write = write_packet,
};

View file

@ -1,7 +1,7 @@
/*
dropin.c -- a set of drop-in replacements for libc functions
Copyright (C) 2000-2005 Ivo Timmermans,
2000-2016 Guus Sliepen <guus@tinc-vpn.org>
2000-2018 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -82,6 +82,8 @@ int daemon(int nochdir, int noclose) {
return 0;
#else
(void)nochdir;
(void)noclose;
return -1;
#endif
}
@ -144,6 +146,7 @@ int gettimeofday(struct timeval *tv, void *tz) {
#ifndef HAVE_NANOSLEEP
int nanosleep(const struct timespec *req, struct timespec *rem) {
(void)rem;
struct timeval tv = {req->tv_sec, req->tv_nsec / 1000};
return select(0, NULL, NULL, NULL, &tv);
}

View file

@ -1,6 +1,6 @@
/*
edge.c -- edge tree management
Copyright (C) 2000-2013 Guus Sliepen <guus@tinc-vpn.org>,
Copyright (C) 2000-2021 Guus Sliepen <guus@tinc-vpn.org>,
2000-2005 Ivo Timmermans
This program is free software; you can redistribute it and/or modify
@ -83,14 +83,26 @@ void free_edge(edge_t *e) {
}
void edge_add(edge_t *e) {
splay_insert(edge_weight_tree, e);
splay_insert(e->from->edge_tree, e);
splay_node_t *node = splay_insert(e->from->edge_tree, e);
if(!node) {
logger(DEBUG_ALWAYS, LOG_ERR, "Edge from %s to %s already exists in edge_tree\n", e->from->name, e->to->name);
return;
}
e->reverse = lookup_edge(e->to, e->from);
if(e->reverse) {
e->reverse->reverse = e;
}
node = splay_insert(edge_weight_tree, e);
if(!node) {
logger(DEBUG_ALWAYS, LOG_ERR, "Edge from %s to %s already exists in edge_weight_tree\n", e->from->name, e->to->name);
return;
}
}
void edge_del(edge_t *e) {

View file

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

View file

@ -1,6 +1,6 @@
/*
event.c -- I/O, timeout and signal event handling
Copyright (C) 2012-2013 Guus Sliepen <guus@tinc-vpn.org>
Copyright (C) 2012-2021 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
@ -378,7 +378,7 @@ bool event_loop(void) {
while(running) {
struct timeval diff;
struct timeval *tv = get_time_remaining(&diff);
DWORD timeout_ms = tv ? (tv->tv_sec * 1000 + tv->tv_usec / 1000 + 1) : WSA_INFINITE;
DWORD timeout_ms = tv ? (DWORD)(tv->tv_sec * 1000 + tv->tv_usec / 1000 + 1) : WSA_INFINITE;
if(!event_count) {
Sleep(timeout_ms);
@ -436,7 +436,7 @@ bool event_loop(void) {
}
if(result < WSA_WAIT_EVENT_0 || result >= WSA_WAIT_EVENT_0 + event_count - event_offset) {
return(false);
return false;
}
/* Look up io in the map by index. */

View file

@ -1,9 +1,9 @@
/*
fd_device.c -- Interaction with Android tun fd
Copyright (C) 2001-2005 Ivo Timmermans,
2001-2016 Guus Sliepen <guus@tinc-vpn.org>
2001-2021 Guus Sliepen <guus@tinc-vpn.org>
2009 Grzegorz Dymarek <gregd72002@googlemail.com>
2016 Pacien TRAN-GIRARD <pacien@pacien.net>
2016-2020 Pacien TRAN-GIRARD <pacien@pacien.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -21,6 +21,10 @@
*/
#include "system.h"
#ifdef HAVE_SYS_UN_H
#include <sys/un.h>
#include "conf.h"
#include "device.h"
#include "ethernet.h"
@ -29,23 +33,132 @@
#include "route.h"
#include "utils.h"
static inline bool check_config(void) {
struct unix_socket_addr {
size_t size;
struct sockaddr_un addr;
};
static int read_fd(int socket) {
char iobuf;
struct iovec iov = {0};
char cmsgbuf[CMSG_SPACE(sizeof(device_fd))];
struct msghdr msg = {0};
int ret;
struct cmsghdr *cmsgptr;
iov.iov_base = &iobuf;
iov.iov_len = 1;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = cmsgbuf;
msg.msg_controllen = sizeof(cmsgbuf);
if((ret = recvmsg(socket, &msg, 0)) < 1) {
logger(DEBUG_ALWAYS, LOG_ERR, "Could not read from unix socket (error %d)!", ret);
return -1;
}
#ifdef IP_RECVERR
if(msg.msg_flags & (MSG_CTRUNC | MSG_OOB | MSG_ERRQUEUE)) {
#else
if(msg.msg_flags & (MSG_CTRUNC | MSG_OOB)) {
#endif
logger(DEBUG_ALWAYS, LOG_ERR, "Error while receiving message (flags %d)!", msg.msg_flags);
return -1;
}
cmsgptr = CMSG_FIRSTHDR(&msg);
if(cmsgptr->cmsg_level != SOL_SOCKET) {
logger(DEBUG_ALWAYS, LOG_ERR, "Wrong CMSG level: %d, expected %d!",
cmsgptr->cmsg_level, SOL_SOCKET);
return -1;
}
if(cmsgptr->cmsg_type != SCM_RIGHTS) {
logger(DEBUG_ALWAYS, LOG_ERR, "Wrong CMSG type: %d, expected %d!",
cmsgptr->cmsg_type, SCM_RIGHTS);
return -1;
}
if(cmsgptr->cmsg_len != CMSG_LEN(sizeof(device_fd))) {
logger(DEBUG_ALWAYS, LOG_ERR, "Wrong CMSG data length: %lu, expected %lu!",
(unsigned long)cmsgptr->cmsg_len, (unsigned long)CMSG_LEN(sizeof(device_fd)));
return -1;
}
return *(int *) CMSG_DATA(cmsgptr);
}
static int receive_fd(struct unix_socket_addr socket_addr) {
int socketfd;
int ret;
int result;
if((socketfd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "Could not open stream socket (error %d)!", socketfd);
return -1;
}
if((ret = connect(socketfd, (struct sockaddr *) &socket_addr.addr, socket_addr.size)) < 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "Could not connect to Unix socket (error %d)!", ret);
result = -1;
goto end;
}
result = read_fd(socketfd);
end:
close(socketfd);
return result;
}
static struct unix_socket_addr parse_socket_addr(const char *path) {
struct sockaddr_un socket_addr;
size_t path_length;
if(strlen(path) >= sizeof(socket_addr.sun_path)) {
logger(DEBUG_ALWAYS, LOG_ERR, "Unix socket path too long!");
return (struct unix_socket_addr) {
0
};
}
socket_addr.sun_family = AF_UNIX;
strncpy(socket_addr.sun_path, path, sizeof(socket_addr.sun_path));
if(path[0] == '@') {
/* abstract namespace socket */
socket_addr.sun_path[0] = '\0';
path_length = strlen(path);
} else {
/* filesystem path with NUL terminator */
path_length = strlen(path) + 1;
}
return (struct unix_socket_addr) {
.size = offsetof(struct sockaddr_un, sun_path) + path_length,
.addr = socket_addr
};
}
static bool setup_device(void) {
if(routing_mode == RMODE_SWITCH) {
logger(DEBUG_ALWAYS, LOG_ERR, "Switch mode not supported (requires unsupported TAP device)!");
return false;
}
if(!get_config_int(lookup_config(config_tree, "Device"), &device_fd)) {
logger(DEBUG_ALWAYS, LOG_ERR, "Could not read fd from configuration!");
if(!get_config_string(lookup_config(config_tree, "Device"), &device)) {
logger(DEBUG_ALWAYS, LOG_ERR, "Could not read device from configuration!");
return false;
}
return true;
}
static bool setup_device(void) {
if(!check_config()) {
return false;
/* device is either directly a file descriptor or an unix socket to read it from */
if(sscanf(device, "%d", &device_fd) != 1) {
logger(DEBUG_ALWAYS, LOG_INFO, "Receiving fd from Unix socket at %s.", device);
device_fd = receive_fd(parse_socket_addr(device));
}
if(device_fd < 0) {
@ -123,3 +236,4 @@ const devops_t fd_devops = {
.read = read_packet,
.write = write_packet,
};
#endif

View file

@ -1,6 +1,6 @@
/*
fsck.c -- Check the configuration files for problems
Copyright (C) 2014 Guus Sliepen <guus@tinc-vpn.org>
Copyright (C) 2014-2021 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
@ -254,7 +254,7 @@ int fsck(const char *argv0) {
return 1;
}
#if !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN)
#ifndef HAVE_MINGW
if(st.st_mode & 077) {
fprintf(stderr, "WARNING: unsafe file permissions on %s.\n", fname);
@ -303,7 +303,7 @@ int fsck(const char *argv0) {
return 1;
}
#if !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN)
#ifndef HAVE_MINGW
if(st.st_mode & 077) {
fprintf(stderr, "WARNING: unsafe file permissions on %s.\n", fname);
@ -385,26 +385,38 @@ int fsck(const char *argv0) {
return 1;
}
char buf1[len], buf2[len], buf3[len];
randomize(buf1, sizeof(buf1));
char *buf1 = malloc(len);
char *buf2 = malloc(len);
char *buf3 = malloc(len);
randomize(buf1, len);
buf1[0] &= 0x7f;
memset(buf2, 0, sizeof(buf2));
memset(buf3, 0, sizeof(buf2));
memset(buf2, 0, len);
memset(buf3, 0, len);
bool result = false;
if(!rsa_public_encrypt(rsa_pub, buf1, sizeof(buf1), buf2)) {
if(rsa_public_encrypt(rsa_pub, buf1, len, buf2)) {
if(rsa_private_decrypt(rsa_priv, buf2, len, buf3)) {
if(memcmp(buf1, buf3, len)) {
result = true;
} else {
fprintf(stderr, "ERROR: public and private RSA keys do not match.\n");
}
} else {
fprintf(stderr, "ERROR: private RSA key does not work.\n");
}
} else {
fprintf(stderr, "ERROR: public RSA key does not work.\n");
}
free(buf3);
free(buf2);
free(buf1);
if(!result) {
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) {

View file

@ -4,7 +4,7 @@
/*
have.h -- include headers which are known to exist
Copyright (C) 1998-2005 Ivo Timmermans
2003-2016 Guus Sliepen <guus@tinc-vpn.org>
2003-2021 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
@ -57,6 +57,10 @@
/* Include system specific headers */
#ifdef HAVE_STDDEF_H
#include <stddef.h>
#endif
#ifdef HAVE_SYSLOG_H
#include <syslog.h>
#endif

View file

@ -1,6 +1,6 @@
/*
ifconfig.c -- Generate platform specific interface configuration commands
Copyright (C) 2016-2017 Guus Sliepen <guus@tinc-vpn.org>
Copyright (C) 2016-2018 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -71,10 +71,12 @@ void ifconfig_dhcp(FILE *out) {
}
void ifconfig_dhcp6(FILE *out) {
(void)out;
fprintf(stderr, "DHCPv6 requested, but not supported by tinc on this platform\n");
}
void ifconfig_slaac(FILE *out) {
(void)out;
// It's the default?
}
@ -126,7 +128,7 @@ void ifconfig_address(FILE *out, const char *value) {
return;
}
#elif defined(HAVE_MINGW) || defined(HAVE_CYGWIN)
#elif defined(HAVE_MINGW)
switch(address.type) {
case SUBNET_MAC:
@ -134,11 +136,11 @@ void ifconfig_address(FILE *out, const char *value) {
break;
case SUBNET_IPV4:
fprintf(out, "netsh inetface ipv4 set address \"$INTERFACE\" static %s\n", address_str);
fprintf(out, "netsh interface 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);
fprintf(out, "netsh interface ipv6 set address \"%%INTERFACE%%\" %s\n", address_str);
break;
default:
@ -199,11 +201,11 @@ void ifconfig_route(FILE *out, const char *value) {
if(*gateway_str) {
switch(subnet.type) {
case SUBNET_IPV4:
fprintf(out, "ip route add %s via %s dev \"$INTERFACE\"\n", subnet_str, gateway_str);
fprintf(out, "ip route add %s via %s dev \"$INTERFACE\" onlink\n", subnet_str, gateway_str);
break;
case SUBNET_IPV6:
fprintf(out, "ip route add %s via %s dev \"$INTERFACE\"\n", subnet_str, gateway_str);
fprintf(out, "ip route add %s via %s dev \"$INTERFACE\" onlink\n", subnet_str, gateway_str);
break;
default:
@ -224,16 +226,16 @@ void ifconfig_route(FILE *out, const char *value) {
}
}
#elif defined(HAVE_MINGW) || defined(HAVE_CYGWIN)
#elif defined(HAVE_MINGW)
if(*gateway_str) {
switch(subnet.type) {
case SUBNET_IPV4:
fprintf(out, "netsh inetface ipv4 add route %s \"%%INTERFACE%%\" %s\n", subnet_str, gateway_str);
fprintf(out, "netsh interface 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);
fprintf(out, "netsh interface ipv6 add route %s \"%%INTERFACE%%\" %s\n", subnet_str, gateway_str);
break;
default:
@ -242,11 +244,11 @@ void ifconfig_route(FILE *out, const char *value) {
} else {
switch(subnet.type) {
case SUBNET_IPV4:
fprintf(out, "netsh inetface ipv4 add route %s \"%%INTERFACE%%\"\n", subnet_str);
fprintf(out, "netsh interface ipv4 add route %s \"%%INTERFACE%%\"\n", subnet_str);
break;
case SUBNET_IPV6:
fprintf(out, "netsh inetface ipv6 add route %s \"%%INTERFACE%%\"\n", subnet_str);
fprintf(out, "netsh interface ipv6 add route %s \"%%INTERFACE%%\"\n", subnet_str);
break;
default:

View file

@ -836,8 +836,12 @@ make_names:
fprintf(stderr, "Ignoring unknown variable '%s' in invitation.\n", l);
continue;
} else if(!(variables[i].type & VAR_SAFE)) {
fprintf(stderr, "Ignoring unsafe variable '%s' in invitation.\n", l);
continue;
if(force) {
fprintf(stderr, "Warning: unsafe variable '%s' in invitation.\n", l);
} else {
fprintf(stderr, "Ignoring unsafe variable '%s' in invitation.\n", l);
continue;
}
}
// Copy the safe variable to the right config file
@ -983,7 +987,12 @@ ask_netname:
char filename2[PATH_MAX];
snprintf(filename, sizeof(filename), "%s" SLASH "tinc-up.invitation", confbase);
#ifdef HAVE_MINGW
snprintf(filename2, sizeof(filename2), "%s" SLASH "tinc-up.bat", confbase);
#else
snprintf(filename2, sizeof(filename2), "%s" SLASH "tinc-up", confbase);
#endif
if(valid_tinc_up) {
if(tty) {
@ -1013,10 +1022,14 @@ ask_netname:
char *command;
#ifndef HAVE_MINGW
const char *editor = getenv("VISUAL");
if (!editor)
if(!editor) {
editor = getenv("EDITOR");
if (!editor)
}
if(!editor) {
editor = "vi";
}
xasprintf(&command, "\"%s\" \"%s\"", editor, filename);
#else

View file

@ -81,7 +81,7 @@ struct ip {
uint8_t ip_p;
uint16_t ip_sum;
struct in_addr ip_src, ip_dst;
} __attribute__((__gcc_struct__, __packed__));
} __attribute__((__gcc_struct__)) __attribute((__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__((__gcc_struct__, __packed__));
} __attribute__((__gcc_struct__)) __attribute((__packed__));
#endif
#endif

View file

@ -49,7 +49,7 @@ struct ip6_hdr {
} ip6_ctlun;
struct in6_addr ip6_src;
struct in6_addr ip6_dst;
} __attribute__((__gcc_struct__, __packed__));
} __attribute__((__gcc_struct__)) __attribute((__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
@ -68,7 +68,7 @@ struct icmp6_hdr {
uint16_t icmp6_un_data16[2];
uint8_t icmp6_un_data8[4];
} icmp6_dataun;
} __attribute__((__gcc_struct__, __packed__));
} __attribute__((__gcc_struct__)) __attribute((__packed__));
#define ICMP6_DST_UNREACH_NOROUTE 0
#define ICMP6_DST_UNREACH 1
#define ICMP6_PACKET_TOO_BIG 2
@ -88,7 +88,7 @@ struct icmp6_hdr {
struct nd_neighbor_solicit {
struct icmp6_hdr nd_ns_hdr;
struct in6_addr nd_ns_target;
} __attribute__((__gcc_struct__, __packed__));
} __attribute__((__gcc_struct__)) __attribute((__packed__));
#define ND_OPT_SOURCE_LINKADDR 1
#define ND_OPT_TARGET_LINKADDR 2
#define nd_ns_type nd_ns_hdr.icmp6_type
@ -101,7 +101,7 @@ struct nd_neighbor_solicit {
struct nd_opt_hdr {
uint8_t nd_opt_type;
uint8_t nd_opt_len;
} __attribute__((__gcc_struct__, __packed__));
} __attribute__((__gcc_struct__)) __attribute((__packed__));
#endif
#endif

View file

@ -1,6 +1,6 @@
/*
meta.c -- handle the meta communication
Copyright (C) 2000-2014 Guus Sliepen <guus@tinc-vpn.org>,
Copyright (C) 2000-2018 Guus Sliepen <guus@tinc-vpn.org>,
2000-2005 Ivo Timmermans
2006 Scott Lamb <slamb@slamb.org>
@ -31,7 +31,9 @@
#include "xalloc.h"
#ifndef MIN
#define MIN(x, y) (((x)<(y))?(x):(y))
static ssize_t MIN(ssize_t x, ssize_t y) {
return x < y ? x : y;
}
#endif
bool send_meta_sptps(void *handle, uint8_t type, const void *buffer, size_t length) {

View file

@ -1,7 +1,7 @@
/*
device.c -- Interaction with Windows tap driver in a MinGW environment
Copyright (C) 2002-2005 Ivo Timmermans,
2002-2014 Guus Sliepen <guus@tinc-vpn.org>
2002-2018 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -71,6 +71,9 @@ static void device_issue_read() {
}
static void device_handle_read(void *data, int flags) {
(void)data;
(void)flags;
DWORD len;
if(!GetOverlappedResult(device_handle, &device_read_overlapped, &len, FALSE)) {
@ -300,6 +303,7 @@ static void close_device(void) {
}
static bool read_packet(vpn_packet_t *packet) {
(void)packet;
return false;
}

View file

@ -1,7 +1,7 @@
/*
names.c -- generate commonly used (file)names
Copyright (C) 1998-2005 Ivo Timmermans
2000-2017 Guus Sliepen <guus@tinc-vpn.org>
2000-2018 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -93,6 +93,7 @@ void make_names(bool daemon) {
}
#ifdef HAVE_MINGW
(void)daemon;
if(!logfilename) {
xasprintf(&logfilename, "%s" SLASH "log", confbase);

View file

@ -1,7 +1,7 @@
/*
net.c -- most of the network code
Copyright (C) 1998-2005 Ivo Timmermans,
2000-2017 Guus Sliepen <guus@tinc-vpn.org>
2000-2021 Guus Sliepen <guus@tinc-vpn.org>
2006 Scott Lamb <slamb@slamb.org>
2011 Loïc Grenié <loic.grenie@gmail.com>
@ -404,20 +404,18 @@ int reload_configuration(void) {
while(cfg) {
subnet_t *subnet, *s2;
if(!get_config_subnet(cfg, &subnet)) {
continue;
}
if(get_config_subnet(cfg, &subnet)) {
if((s2 = lookup_subnet(myself, subnet))) {
if(s2->expires == 1) {
s2->expires = 0;
}
if((s2 = lookup_subnet(myself, subnet))) {
if(s2->expires == 1) {
s2->expires = 0;
free_subnet(subnet);
} else {
subnet_add(myself, subnet);
send_add_subnet(everyone, subnet);
subnet_update(myself, subnet, true);
}
free_subnet(subnet);
} else {
subnet_add(myself, subnet);
send_add_subnet(everyone, subnet);
subnet_update(myself, subnet, true);
}
cfg = lookup_config_next(config_tree, cfg);

View file

@ -121,7 +121,6 @@ typedef struct listen_socket_t {
typedef struct outgoing_t {
struct node_t *node;
int timeout;
struct address_cache_t *address_cache;
timeout_t ev;
} outgoing_t;

View file

@ -1,7 +1,7 @@
/*
net_packet.c -- Handles in- and outgoing VPN packets
Copyright (C) 1998-2005 Ivo Timmermans,
2000-2017 Guus Sliepen <guus@tinc-vpn.org>
2000-2021 Guus Sliepen <guus@tinc-vpn.org>
2010 Timothy Redaelli <timothy@redaelli.eu>
2010 Brandon Black <blblack@gmail.com>
@ -152,11 +152,12 @@ static void udp_probe_h(node_t *n, vpn_packet_t *packet, length_t len) {
len = ntohs(len16);
}
if(n->udp_ping_sent.tv_sec != 0) { // a probe in flight
if(n->status.ping_sent) { // a probe in flight
gettimeofday(&now, NULL);
struct timeval rtt;
timersub(&now, &n->udp_ping_sent, &rtt);
n->udp_ping_rtt = rtt.tv_sec * 1000000 + rtt.tv_usec;
n->status.ping_sent = false;
logger(DEBUG_TRAFFIC, LOG_INFO, "Got type %d UDP probe reply %d from %s (%s) rtt=%d.%03d", DATA(packet)[0], len, n->name, n->hostname, n->udp_ping_rtt / 1000, n->udp_ping_rtt % 1000);
} else {
logger(DEBUG_TRAFFIC, LOG_INFO, "Got type %d UDP probe reply %d from %s (%s)", DATA(packet)[0], len, n->name, n->hostname);
@ -175,8 +176,7 @@ static void udp_probe_h(node_t *n, vpn_packet_t *packet, length_t len) {
reset_address_cache(n->address_cache, &n->address);
}
// Reset the UDP ping timer. (no probe in flight)
n->udp_ping_sent.tv_sec = 0;
// Reset the UDP ping timer.
if(udp_discovery) {
timeout_del(&n->udp_ping_timeout);
@ -314,13 +314,6 @@ static bool try_mac(node_t *n, const vpn_packet_t *inpkt) {
}
static bool receive_udppacket(node_t *n, vpn_packet_t *inpkt) {
vpn_packet_t pkt1, pkt2;
vpn_packet_t *pkt[] = { &pkt1, &pkt2, &pkt1, &pkt2 };
int nextpkt = 0;
size_t outlen;
pkt1.offset = DEFAULT_PACKET_OFFSET;
pkt2.offset = DEFAULT_PACKET_OFFSET;
if(n->status.sptps) {
if(!n->sptps.state) {
if(!n->status.waitingforkey) {
@ -356,6 +349,12 @@ static bool receive_udppacket(node_t *n, vpn_packet_t *inpkt) {
#ifdef DISABLE_LEGACY
return false;
#else
vpn_packet_t pkt1, pkt2;
vpn_packet_t *pkt[] = { &pkt1, &pkt2, &pkt1, &pkt2 };
int nextpkt = 0;
size_t outlen;
pkt1.offset = DEFAULT_PACKET_OFFSET;
pkt2.offset = DEFAULT_PACKET_OFFSET;
if(!n->status.validkey_in) {
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet", n->name, n->hostname);
@ -546,7 +545,10 @@ bool receive_tcppacket_sptps(connection_t *c, const char *data, size_t len) {
/* If we're not the final recipient, relay the packet. */
if(to != myself) {
send_sptps_data(to, from, 0, data, len);
if(to->status.validkey) {
send_sptps_data(to, from, 0, data, len);
}
try_tx(to, true);
return true;
}
@ -699,18 +701,6 @@ static void choose_local_address(const node_t *n, const sockaddr_t **sa, int *so
}
static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
vpn_packet_t pkt1, pkt2;
vpn_packet_t *pkt[] = { &pkt1, &pkt2, &pkt1, &pkt2 };
vpn_packet_t *inpkt = origpkt;
int nextpkt = 0;
vpn_packet_t *outpkt;
int origlen = origpkt->len;
size_t outlen;
int origpriority = origpkt->priority;
pkt1.offset = DEFAULT_PACKET_OFFSET;
pkt2.offset = DEFAULT_PACKET_OFFSET;
if(!n->status.reachable) {
logger(DEBUG_TRAFFIC, LOG_INFO, "Trying to send UDP packet to unreachable node %s (%s)", n->name, n->hostname);
return;
@ -724,6 +714,18 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
#ifdef DISABLE_LEGACY
return;
#else
vpn_packet_t pkt1, pkt2;
vpn_packet_t *pkt[] = { &pkt1, &pkt2, &pkt1, &pkt2 };
vpn_packet_t *inpkt = origpkt;
int nextpkt = 0;
vpn_packet_t *outpkt;
int origlen = origpkt->len;
size_t outlen;
int origpriority = origpkt->priority;
pkt1.offset = DEFAULT_PACKET_OFFSET;
pkt2.offset = DEFAULT_PACKET_OFFSET;
/* Make sure we have a valid key */
if(!n->status.validkey) {
@ -1133,6 +1135,7 @@ static void try_udp(node_t *n) {
if(ping_tx_elapsed.tv_sec >= interval) {
gettimeofday(&now, NULL);
n->udp_ping_sent = now; // a probe in flight
n->status.ping_sent = true;
send_udp_probe_packet(n, MIN_PROBE_SIZE);
if(localdiscovery && !n->status.udp_confirmed && n->prevedge) {
@ -1229,9 +1232,8 @@ static length_t choose_initial_maxmtu(node_t *n) {
return mtu;
#else
(void)n;
return MTU;
#endif
}
@ -1776,13 +1778,13 @@ void handle_incoming_vpn_data(void *data, int flags) {
#else
vpn_packet_t pkt;
sockaddr_t addr = {};
sockaddr_t addr = {0};
socklen_t addrlen = sizeof(addr);
pkt.offset = 0;
int len = recvfrom(ls->udp.fd, (void *)DATA(&pkt), MAXSIZE, 0, &addr.sa, &addrlen);
if(len <= 0 || len > MAXSIZE) {
if(len <= 0 || (size_t)len > MAXSIZE) {
if(!sockwouldblock(sockerrno)) {
logger(DEBUG_ALWAYS, LOG_ERR, "Receiving packet failed: %s", sockstrerror(sockerrno));
}

View file

@ -1,7 +1,7 @@
/*
net_setup.c -- Setup.
Copyright (C) 1998-2005 Ivo Timmermans,
2000-2017 Guus Sliepen <guus@tinc-vpn.org>
2000-2021 Guus Sliepen <guus@tinc-vpn.org>
2006 Scott Lamb <slamb@slamb.org>
2010 Brandon Black <blblack@gmail.com>
@ -215,14 +215,14 @@ static bool read_ecdsa_private_key(void) {
logger(DEBUG_ALWAYS, LOG_ERR, "Error reading Ed25519 private key file `%s': %s", fname, strerror(errno));
if(errno == ENOENT) {
logger(DEBUG_ALWAYS, LOG_INFO, "Create an Ed25519 keypair with `tinc -n %s generate-ed25519-keys'.", netname ? netname : ".");
logger(DEBUG_ALWAYS, LOG_INFO, "Create an Ed25519 key pair with `tinc -n %s generate-ed25519-keys'.", netname ? netname : ".");
}
free(fname);
return false;
}
#if !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN)
#ifndef HAVE_MINGW
struct stat s;
if(fstat(fileno(fp), &s)) {
@ -307,14 +307,14 @@ static bool read_rsa_private_key(void) {
fname, strerror(errno));
if(errno == ENOENT) {
logger(DEBUG_ALWAYS, LOG_INFO, "Create an RSA keypair with `tinc -n %s generate-rsa-keys'.", netname ? netname : ".");
logger(DEBUG_ALWAYS, LOG_INFO, "Create an RSA key pair with `tinc -n %s generate-rsa-keys'.", netname ? netname : ".");
}
free(fname);
return false;
}
#if !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN)
#ifndef HAVE_MINGW
struct stat s;
if(fstat(fileno(fp), &s)) {
@ -341,6 +341,7 @@ static bool read_rsa_private_key(void) {
}
#endif
#ifndef DISABLE_LEGACY
static timeout_t keyexpire_timeout;
static void keyexpire_handler(void *data) {
@ -349,6 +350,7 @@ static void keyexpire_handler(void *data) {
keylifetime, rand() % 100000
});
}
#endif
void regenerate_key(void) {
logger(DEBUG_STATUS, LOG_INFO, "Expiring symmetric keys");
@ -822,7 +824,7 @@ void device_disable(void) {
Configure node_t myself and set up the local sockets (listen only)
*/
static bool setup_myself(void) {
char *name, *hostname, *cipher, *digest, *type;
char *name, *hostname, *type;
char *address = NULL;
bool port_specified = false;
@ -967,6 +969,8 @@ static bool setup_myself(void) {
#ifndef DISABLE_LEGACY
/* Generate packet encryption key */
char *cipher;
if(!get_config_string(lookup_config(config_tree, "Cipher"), &cipher)) {
cipher = xstrdup("aes-256-cbc");
}
@ -995,6 +999,8 @@ static bool setup_myself(void) {
return false;
}
char *digest;
if(!get_config_string(lookup_config(config_tree, "Digest"), &digest)) {
digest = xstrdup("sha256");
}
@ -1047,10 +1053,14 @@ static bool setup_myself(void) {
devops = raw_socket_devops;
} else if(!strcasecmp(type, "multicast")) {
devops = multicast_devops;
} else if(!strcasecmp(type, "fd")) {
}
#ifdef HAVE_SYS_UN_H
else if(!strcasecmp(type, "fd")) {
devops = fd_devops;
}
#endif
#ifdef ENABLE_UML
else if(!strcasecmp(type, "uml")) {
devops = uml_devops;

View file

@ -1,7 +1,7 @@
/*
net_socket.c -- Handle various kinds of sockets.
Copyright (C) 1998-2005 Ivo Timmermans,
2000-2017 Guus Sliepen <guus@tinc-vpn.org>
2000-2018 Guus Sliepen <guus@tinc-vpn.org>
2006 Scott Lamb <slamb@slamb.org>
2009 Florian Forster <octo@verplant.org>
@ -122,6 +122,7 @@ static bool bind_to_interface(int sd) {
}
#else /* if !defined(SOL_SOCKET) || !defined(SO_BINDTODEVICE) */
(void)sd;
logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform", "BindToInterface");
#endif
@ -387,7 +388,7 @@ void finish_connecting(connection_t *c) {
send_id(c);
}
static void do_outgoing_pipe(connection_t *c, char *command) {
static void do_outgoing_pipe(connection_t *c, const char *command) {
#ifndef HAVE_MINGW
int fd[2];
@ -435,6 +436,8 @@ static void do_outgoing_pipe(connection_t *c, char *command) {
exit(result);
#else
(void)c;
(void)command;
logger(DEBUG_ALWAYS, LOG_ERR, "Proxy type exec not supported on this platform!");
return;
#endif
@ -524,7 +527,7 @@ bool do_outgoing_connection(outgoing_t *outgoing) {
int result;
begin:
sa = get_recent_address(outgoing->address_cache);
sa = get_recent_address(outgoing->node->address_cache);
if(!sa) {
logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not set up a meta connection to %s", outgoing->node->name);
@ -629,6 +632,10 @@ void setup_outgoing_connection(outgoing_t *outgoing, bool verbose) {
node_t *n = outgoing->node;
if(!n->address_cache) {
n->address_cache = open_address_cache(n);
}
if(n->connection) {
logger(DEBUG_CONNECTIONS, LOG_INFO, "Already connected to %s", n->name);
@ -640,10 +647,6 @@ void setup_outgoing_connection(outgoing_t *outgoing, bool verbose) {
}
}
if(!outgoing->address_cache) {
outgoing->address_cache = open_address_cache(n);
}
do_outgoing_connection(outgoing);
return;
@ -784,11 +787,6 @@ void handle_new_unix_connection(void *data, int flags) {
static void free_outgoing(outgoing_t *outgoing) {
timeout_del(&outgoing->ev);
if(outgoing->address_cache) {
close_address_cache(outgoing->address_cache);
}
free(outgoing);
}

View file

@ -41,7 +41,8 @@ typedef struct node_status_t {
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 has_address: 1; /* 1 if we know an external address for this node */
unsigned int unused: 20;
unsigned int ping_sent: 1; /* 1 if we sent a UDP probe but haven't received the reply yet */
unsigned int unused: 19;
} node_status_t;
typedef struct node_t {

View file

@ -1,6 +1,6 @@
/*
crypto.c -- Cryptographic miscellaneous functions and initialisation
Copyright (C) 2007-2014 Guus Sliepen <guus@tinc-vpn.org>
Copyright (C) 2007-2021 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
@ -42,12 +42,14 @@ static void random_exit(void) {
close(random_fd);
}
void randomize(void *out, size_t outlen) {
void randomize(void *vout, size_t outlen) {
char *out = vout;
while(outlen) {
size_t len = read(random_fd, out, outlen);
ssize_t len = read(random_fd, out, outlen);
if(len <= 0) {
if(errno == EAGAIN || errno == EINTR) {
if(len == -1 && (errno == EAGAIN || errno == EINTR)) {
continue;
}

View file

@ -189,7 +189,7 @@ bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou
} else {
int len;
if(EVP_EncryptUpdate(cipher->ctx, outdata, &len, indata, inlen)) {
if(EVP_DecryptUpdate(cipher->ctx, outdata, &len, indata, inlen)) {
if(outlen) {
*outlen = len;
}

View file

@ -1,6 +1,6 @@
/*
crypto.c -- Cryptographic miscellaneous functions and initialisation
Copyright (C) 2007-2014 Guus Sliepen <guus@tinc-vpn.org>
Copyright (C) 2007-2021 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
@ -50,10 +50,10 @@ void randomize(void *vout, size_t outlen) {
char *out = vout;
while(outlen) {
size_t len = read(random_fd, out, outlen);
ssize_t len = read(random_fd, out, outlen);
if(len <= 0) {
if(errno == EAGAIN || errno == EINTR) {
if(len == -1 && (errno == EAGAIN || errno == EINTR)) {
continue;
}
@ -96,9 +96,10 @@ void crypto_init(void) {
ENGINE_load_builtin_engines();
ENGINE_register_all_complete();
#if OPENSSL_API_COMPAT < 0x10100000L
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();
#endif
if(!RAND_status()) {
fprintf(stderr, "Not enough entropy for the PRNG!\n");
@ -107,8 +108,10 @@ void crypto_init(void) {
}
void crypto_exit(void) {
#if OPENSSL_API_COMPAT < 0x10100000L
EVP_cleanup();
ERR_free_strings();
ENGINE_cleanup();
#endif
random_exit();
}

View file

@ -1,6 +1,6 @@
/*
rsa.c -- RSA key handling
Copyright (C) 2007-2013 Guus Sliepen <guus@tinc-vpn.org>
Copyright (C) 2007-2021 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 <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/rsa.h>
#define TINC_RSA_INTERNAL
typedef RSA rsa_t;

View file

@ -1,7 +1,7 @@
/*
process.c -- process management functions
Copyright (C) 1999-2005 Ivo Timmermans,
2000-2013 Guus Sliepen <guus@tinc-vpn.org>
2000-2018 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -115,7 +115,11 @@ static bool install_service(void) {
io_t stop_io;
DWORD WINAPI controlhandler(DWORD request, DWORD type, LPVOID boe, LPVOID bah) {
DWORD WINAPI controlhandler(DWORD request, DWORD type, LPVOID data, LPVOID context) {
(void)type;
(void)data;
(void)context;
switch(request) {
case SERVICE_CONTROL_INTERROGATE:
SetServiceStatus(statushandle, &status);

View file

@ -284,13 +284,16 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const void *dat
}
// Read the new node's Name from the file
char buf[1024];
char buf[1024] = "";
fgets(buf, sizeof(buf), f);
size_t buflen = strlen(buf);
if(*buf) {
buf[strlen(buf) - 1] = 0;
// Strip whitespace at the end
while(buflen && strchr(" \t\r\n", buf[buflen - 1])) {
buf[--buflen] = 0;
}
// Split the first line into variable and value
len = strcspn(buf, " \t=");
char *name = buf + len;
name += strspn(name, " \t");
@ -302,6 +305,7 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const void *dat
buf[len] = 0;
// Check that it is a valid Name
if(!*buf || !*name || strcasecmp(buf, "Name") || !check_id(name) || !strcmp(name, myself->name)) {
logger(DEBUG_ALWAYS, LOG_ERR, "Invalid invitation file %s\n", cookie);
fclose(f);
@ -486,11 +490,8 @@ bool id_h(connection_t *c, const char *request) {
}
}
#ifndef DISABLE_LEGACY
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;
@ -580,14 +581,9 @@ 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;
}
@ -655,13 +651,9 @@ 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];
@ -678,14 +670,9 @@ 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;
}
@ -720,8 +707,6 @@ bool challenge_h(connection_t *c, const char *request) {
} else {
return true;
}
#endif
}
bool send_chal_reply(connection_t *c) {
@ -748,9 +733,6 @@ bool send_chal_reply(connection_t *c) {
}
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) {
@ -791,13 +773,9 @@ bool chal_reply_h(connection_t *c, const char *request) {
}
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. */
@ -810,8 +788,46 @@ static bool send_upgrade(connection_t *c) {
bool result = send_request(c, "%d %s", ACK, pubkey);
free(pubkey);
return result;
#endif
}
#else
bool send_metakey(connection_t *c) {
(void)c;
return false;
}
bool metakey_h(connection_t *c, const char *request) {
(void)c;
(void)request;
return false;
}
bool send_challenge(connection_t *c) {
(void)c;
return false;
}
bool challenge_h(connection_t *c, const char *request) {
(void)c;
(void)request;
return false;
}
bool send_chal_reply(connection_t *c) {
(void)c;
return false;
}
bool chal_reply_h(connection_t *c, const char *request) {
(void)c;
(void)request;
return false;
}
static bool send_upgrade(connection_t *c) {
(void)c;
return false;
}
#endif
bool send_ack(connection_t *c) {
if(c->protocol_minor == 1) {

View file

@ -34,7 +34,9 @@
#include "utils.h"
#include "xalloc.h"
#ifndef DISABLE_LEGACY
static bool mykeyused = false;
#endif
void send_key_changed(void) {
#ifndef DISABLE_LEGACY

View file

@ -71,9 +71,9 @@ bool pong_h(connection_t *c, const char *request) {
/* Successful connection, reset timeout if this is an outgoing connection. */
if(c->outgoing) {
if(c->outgoing && c->outgoing->timeout) {
c->outgoing->timeout = 0;
reset_address_cache(c->outgoing->address_cache, &c->address);
reset_address_cache(c->outgoing->node->address_cache, &c->address);
}
return true;

View file

@ -1,7 +1,7 @@
/*
route.c -- routing
Copyright (C) 2000-2005 Ivo Timmermans,
2000-2013 Guus Sliepen <guus@tinc-vpn.org>
2000-2018 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -59,33 +59,30 @@ static const size_t opt_size = sizeof(struct nd_opt_hdr);
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#endif
volatile int dummy;
static timeout_t age_subnets_timeout;
/* RFC 1071 */
static uint16_t inet_checksum(void *data, int len, uint16_t prevsum) {
uint16_t *p = data;
static uint16_t inet_checksum(void *vdata, int len, uint16_t prevsum) {
uint8_t *data = vdata;
uint16_t word;
uint32_t checksum = prevsum ^ 0xFFFF;
while(len >= 2) {
checksum += *p++;
memcpy(&word, data, sizeof(word));
checksum += word;
data += 2;
len -= 2;
}
if(len) {
checksum += *(uint8_t *)p;
checksum += *data;
}
while(checksum >> 16) {
checksum = (checksum & 0xFFFF) + (checksum >> 16);
}
// Work around a compiler optimization bug.
if(checksum) {
dummy = 1;
}
return ~checksum;
}
@ -165,7 +162,7 @@ static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, length_
addr.sin_family = AF_INET;
socklen_t addrlen = sizeof(addr);
if(!getsockname(sockfd, (struct sockaddr *) &addr, &addrlen) && addrlen <= sizeof(addr)) {
if(!getsockname(sockfd, (struct sockaddr *) &addr, &addrlen) && (size_t)addrlen <= sizeof(addr)) {
ip_dst = addr.sin_addr;
}
}
@ -270,7 +267,7 @@ static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, length_
addr.sin6_family = AF_INET6;
socklen_t addrlen = sizeof(addr);
if(!getsockname(sockfd, (struct sockaddr *) &addr, &addrlen) && addrlen <= sizeof(addr)) {
if(!getsockname(sockfd, (struct sockaddr *) &addr, &addrlen) && (size_t)addrlen <= sizeof(addr)) {
pseudo.ip6_src = addr.sin6_addr;
}
}
@ -598,7 +595,7 @@ static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t et
logger(DEBUG_TRAFFIC, LOG_INFO, "Fragmenting packet of %d bytes to %s (%s)", packet->len, dest->name, dest->hostname);
offset = DATA(packet) + ether_size + ip_size;
maxlen = (dest->mtu - ether_size - ip_size) & ~0x7;
maxlen = (MAX(dest->mtu, 590) - ether_size - ip_size) & ~0x7;
ip_off = ntohs(ip.ip_off);
origf = ip_off & ~IP_OFFMASK;
ip_off &= IP_OFFMASK;

View file

@ -1,7 +1,7 @@
/*
script.c -- call an external script
Copyright (C) 1999-2005 Ivo Timmermans,
2000-2017 Guus Sliepen <guus@tinc-vpn.org>
2000-2018 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -50,7 +50,7 @@ static void unputenv(const char *p) {
#else
// We must keep what we putenv() around in memory.
// To do this without memory leaks, keep things in a list and reuse if possible.
static list_t list = {};
static list_t list = {0};
for list_each(char, data, &list) {
if(!strcmp(data, var)) {
@ -142,7 +142,12 @@ bool execute_script(const char *name, environment_t *env) {
#ifdef HAVE_MINGW
if(!*scriptextension) {
const char *pathext = getenv("PATHEXT") ? : ".COM;.EXE;.BAT;.CMD";
const char *pathext = getenv("PATHEXT");
if(!pathext) {
pathext = ".COM;.EXE;.BAT;.CMD";
}
size_t pathlen = strlen(pathext);
size_t scriptlen = strlen(scriptname);
char fullname[scriptlen + pathlen + 1];

View file

@ -78,6 +78,7 @@ static bool send_data(void *handle, uint8_t type, const void *data, size_t len)
static bool receive_record(void *handle, uint8_t type, const void *data, uint16_t len) {
(void)handle;
if(verbose) {
fprintf(stderr, "Received type %d record of %u bytes:\n", type, len);
}
@ -369,6 +370,7 @@ int main(int argc, char *argv[]) {
}
char buf[65535] = "";
size_t readsize = datagram ? 1460u : sizeof(buf);
fd_set fds;
FD_ZERO(&fds);
@ -386,7 +388,7 @@ int main(int argc, char *argv[]) {
}
if(FD_ISSET(in, &fds)) {
ssize_t len = read(in, buf, sizeof(buf));
ssize_t len = read(in, buf, readsize);
if(len < 0) {
fprintf(stderr, "Could not read from stdin: %s\n", strerror(errno));

View file

@ -3,7 +3,7 @@
/*
subnet.h -- header for subnet.c
Copyright (C) 2000-2012 Guus Sliepen <guus@tinc-vpn.org>,
Copyright (C) 2000-2021 Guus Sliepen <guus@tinc-vpn.org>,
2000-2005 Ivo Timmermans
This program is free software; you can redistribute it and/or modify
@ -78,6 +78,7 @@ extern void subnet_update(struct node_t *owner, subnet_t *subnet, bool up);
extern int maskcmp(const void *a, const void *b, int masklen);
extern void maskcpy(void *dest, const void *src, int masklen, int len);
extern void mask(void *mask, int masklen, int len);
extern bool subnetcheck(const subnet_t subnet);
extern bool maskcheck(const void *mask, int masklen, int len);
extern bool net2str(char *netstr, int len, const subnet_t *subnet);
extern bool str2net(subnet_t *subnet, const char *netstr);

View file

@ -1,6 +1,6 @@
/*
subnet_parse.c -- handle subnet parsing
Copyright (C) 2000-2012 Guus Sliepen <guus@tinc-vpn.org>,
Copyright (C) 2000-2021 Guus Sliepen <guus@tinc-vpn.org>,
2000-2005 Ivo Timmermans
This program is free software; you can redistribute it and/or modify
@ -87,6 +87,17 @@ void maskcpy(void *va, const void *vb, int masklen, int len) {
}
}
bool subnetcheck(const subnet_t subnet) {
if(((subnet.type == SUBNET_IPV4)
&& !maskcheck(&subnet.net.ipv4.address, subnet.net.ipv4.prefixlength, sizeof(subnet.net.ipv4.address)))
|| ((subnet.type == SUBNET_IPV6)
&& !maskcheck(&subnet.net.ipv6.address, subnet.net.ipv6.prefixlength, sizeof(subnet.net.ipv6.address)))) {
return false;
}
return true;
}
bool maskcheck(const void *va, int masklen, int len) {
int i;
const char *a = va;

View file

@ -1,6 +1,6 @@
/*
tincctl.c -- Controlling a running tincd
Copyright (C) 2007-2018 Guus Sliepen <guus@tinc-vpn.org>
Copyright (C) 2007-2021 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
@ -40,6 +40,7 @@
#include "tincctl.h"
#include "top.h"
#include "version.h"
#include "subnet.h"
#ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0
@ -125,12 +126,12 @@ static void usage(bool status) {
" reload Partially reload configuration of running tincd.\n"
" pid Show PID of currently running tincd.\n"
#ifdef DISABLE_LEGACY
" generate-keys Generate a new Ed25519 public/private keypair.\n"
" generate-keys Generate a new Ed25519 public/private key pair.\n"
#else
" generate-keys [bits] Generate new RSA and Ed25519 public/private keypairs.\n"
" generate-rsa-keys [bits] Generate a new RSA public/private keypair.\n"
" generate-keys [bits] Generate new RSA and Ed25519 public/private key pairs.\n"
" generate-rsa-keys [bits] Generate a new RSA public/private key pair.\n"
#endif
" generate-ed25519-keys Generate a new Ed25519 public/private keypair.\n"
" generate-ed25519-keys Generate a new Ed25519 public/private key pair.\n"
" dump Dump a list of one of the following things:\n"
" [reachable] nodes - all known nodes in the VPN\n"
" edges - all known connections in the VPN\n"
@ -237,7 +238,7 @@ static bool parse_options(int argc, char **argv) {
FILE *fopenmask(const char *filename, const char *mode, mode_t perms) {
mode_t mask = umask(0);
perms &= ~mask;
umask(~perms);
umask(~perms & 0777);
FILE *f = fopen(filename, mode);
if(!f) {
@ -262,19 +263,21 @@ static void disable_old_keys(const char *filename, const char *what) {
bool disabled = false;
bool block = false;
bool error = false;
FILE *r, *w;
r = fopen(filename, "r");
FILE *r = fopen(filename, "r");
FILE *w = NULL;
if(!r) {
return;
}
snprintf(tmpfile, sizeof(tmpfile), "%s.tmp", filename);
int result = snprintf(tmpfile, sizeof(tmpfile), "%s.tmp", filename);
struct stat st = {.st_mode = 0600};
fstat(fileno(r), &st);
w = fopenmask(tmpfile, "w", st.st_mode);
if(result < sizeof(tmpfile)) {
struct stat st = {.st_mode = 0600};
fstat(fileno(r), &st);
w = fopenmask(tmpfile, "w", st.st_mode);
}
while(fgets(buf, sizeof(buf), r)) {
if(!block && !strncmp(buf, "-----BEGIN ", 11)) {
@ -416,7 +419,7 @@ ask_filename:
}
/*
Generate a public/private Ed25519 keypair, and ask for a file to store
Generate a public/private Ed25519 key pair, and ask for a file to store
them in.
*/
static bool ed25519_keygen(bool ask) {
@ -424,7 +427,7 @@ static bool ed25519_keygen(bool ask) {
FILE *f;
char fname[PATH_MAX];
fprintf(stderr, "Generating Ed25519 keypair:\n");
fprintf(stderr, "Generating Ed25519 key pair:\n");
if(!(key = ecdsa_generate())) {
fprintf(stderr, "Error during key generation!\n");
@ -480,7 +483,7 @@ error:
#ifndef DISABLE_LEGACY
/*
Generate a public/private RSA keypair, and ask for a file to store
Generate a public/private RSA key pair, and ask for a file to store
them in.
*/
static bool rsa_keygen(int bits, bool ask) {
@ -725,6 +728,24 @@ static void logcontrol(int fd, FILE *out, int level) {
}
}
static bool stop_tincd(void) {
if(!connect_tincd(true)) {
return false;
}
sendline(fd, "%d %d", CONTROL, REQ_STOP);
while(recvline(fd, line, sizeof(line))) {
// wait for tincd to close the connection...
}
close(fd);
pid = 0;
fd = -1;
return true;
}
#ifdef HAVE_MINGW
static bool remove_service(void) {
SC_HANDLE manager = NULL;
@ -742,7 +763,12 @@ static bool remove_service(void) {
service = OpenService(manager, identname, SERVICE_ALL_ACCESS);
if(!service) {
fprintf(stderr, "Could not open %s service: %s\n", identname, winerror(GetLastError()));
if(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST) {
success = stop_tincd();
} else {
fprintf(stderr, "Could not open %s service: %s\n", identname, winerror(GetLastError()));
}
goto exit;
}
@ -883,7 +909,6 @@ bool connect_tincd(bool verbose) {
return false;
}
#ifdef HAVE_MINGW
unsigned long arg = 0;
if(ioctlsocket(fd, FIONBIO, &arg) != 0) {
@ -892,8 +917,6 @@ bool connect_tincd(bool verbose) {
}
}
#endif
if(connect(fd, res->ai_addr, res->ai_addrlen) < 0) {
if(verbose) {
fprintf(stderr, "Cannot connect to %s port %s: %s\n", host, port, sockstrerror(sockerrno));
@ -1083,9 +1106,11 @@ static int cmd_stop(int argc, char *argv[]) {
return 1;
}
#ifndef HAVE_MINGW
#ifdef HAVE_MINGW
return remove_service();
#else
if(!connect_tincd(true)) {
if(!stop_tincd()) {
if(pid) {
if(kill(pid, SIGTERM)) {
fprintf(stderr, "Could not send TERM signal to process with PID %d: %s\n", pid, strerror(errno));
@ -1100,24 +1125,8 @@ static int cmd_stop(int argc, char *argv[]) {
return 1;
}
sendline(fd, "%d %d", CONTROL, REQ_STOP);
while(recvline(fd, line, sizeof(line))) {
// Wait for tincd to close the connection...
}
#else
if(!remove_service()) {
return 1;
}
#endif
close(fd);
pid = 0;
fd = -1;
return 0;
#endif
}
static int cmd_restart(int argc, char *argv[]) {
@ -1346,7 +1355,7 @@ static int cmd_dump(int argc, char *argv[]) {
color = "green";
}
printf(" %s [label = \"%s\", color = \"%s\"%s];\n", node, node, color, strcmp(host, "MYSELF") ? "" : ", style = \"filled\"");
printf(" \"%s\" [label = \"%s\", color = \"%s\"%s];\n", node, node, color, strcmp(host, "MYSELF") ? "" : ", style = \"filled\"");
} else {
if(only_reachable && !status.reachable) {
continue;
@ -1376,9 +1385,9 @@ static int cmd_dump(int argc, char *argv[]) {
float w = 1 + 65536.0 / weight;
if(do_graph == 1 && strcmp(node1, node2) > 0) {
printf(" %s -- %s [w = %f, weight = %f];\n", node1, node2, w, w);
printf(" \"%s\" -- \"%s\" [w = %f, weight = %f];\n", node1, node2, w, w);
} else if(do_graph == 2) {
printf(" %s -> %s [w = %f, weight = %f];\n", node1, node2, w, w);
printf(" \"%s\" -> \"%s\" [w = %f, weight = %f];\n", node1, node2, w, w);
}
} else {
printf("%s to %s at %s port %s local %s port %s options %x weight %d\n", from, to, host, port, local_host, local_port, options, weight);
@ -1717,18 +1726,18 @@ ecdsa_t *get_pubkey(FILE *f) {
const var_t variables[] = {
/* Server configuration */
{"AddressFamily", VAR_SERVER},
{"AddressFamily", VAR_SERVER | VAR_SAFE},
{"AutoConnect", VAR_SERVER | VAR_SAFE},
{"BindToAddress", VAR_SERVER | VAR_MULTIPLE},
{"BindToInterface", VAR_SERVER},
{"Broadcast", VAR_SERVER | VAR_SAFE},
{"BroadcastSubnet", VAR_SERVER | VAR_MULTIPLE | VAR_SAFE},
{"ConnectTo", VAR_SERVER | VAR_MULTIPLE | VAR_SAFE},
{"DecrementTTL", VAR_SERVER},
{"DecrementTTL", VAR_SERVER | VAR_SAFE},
{"Device", VAR_SERVER},
{"DeviceStandby", VAR_SERVER},
{"DeviceType", VAR_SERVER},
{"DirectOnly", VAR_SERVER},
{"DirectOnly", VAR_SERVER | VAR_SAFE},
{"Ed25519PrivateKeyFile", VAR_SERVER},
{"ExperimentalProtocol", VAR_SERVER},
{"Forwarding", VAR_SERVER},
@ -1738,34 +1747,34 @@ const var_t variables[] = {
{"IffOneQueue", VAR_SERVER},
{"Interface", VAR_SERVER},
{"InvitationExpire", VAR_SERVER},
{"KeyExpire", VAR_SERVER},
{"KeyExpire", VAR_SERVER | VAR_SAFE},
{"ListenAddress", VAR_SERVER | VAR_MULTIPLE},
{"LocalDiscovery", VAR_SERVER},
{"LocalDiscovery", VAR_SERVER | VAR_SAFE},
{"LogLevel", VAR_SERVER},
{"MACExpire", VAR_SERVER},
{"MaxConnectionBurst", VAR_SERVER},
{"MaxOutputBufferSize", VAR_SERVER},
{"MaxTimeout", VAR_SERVER},
{"MACExpire", VAR_SERVER | VAR_SAFE},
{"MaxConnectionBurst", VAR_SERVER | VAR_SAFE},
{"MaxOutputBufferSize", VAR_SERVER | VAR_SAFE},
{"MaxTimeout", VAR_SERVER | VAR_SAFE},
{"Mode", VAR_SERVER | VAR_SAFE},
{"Name", VAR_SERVER},
{"PingInterval", VAR_SERVER},
{"PingTimeout", VAR_SERVER},
{"PingInterval", VAR_SERVER | VAR_SAFE},
{"PingTimeout", VAR_SERVER | VAR_SAFE},
{"PriorityInheritance", VAR_SERVER},
{"PrivateKey", VAR_SERVER | VAR_OBSOLETE},
{"PrivateKeyFile", VAR_SERVER},
{"ProcessPriority", VAR_SERVER},
{"Proxy", VAR_SERVER},
{"ReplayWindow", VAR_SERVER},
{"ReplayWindow", VAR_SERVER | VAR_SAFE},
{"ScriptsExtension", VAR_SERVER},
{"ScriptsInterpreter", VAR_SERVER},
{"StrictSubnets", VAR_SERVER},
{"TunnelServer", VAR_SERVER},
{"UDPDiscovery", VAR_SERVER},
{"UDPDiscoveryKeepaliveInterval", VAR_SERVER},
{"UDPDiscoveryInterval", VAR_SERVER},
{"UDPDiscoveryTimeout", VAR_SERVER},
{"MTUInfoInterval", VAR_SERVER},
{"UDPInfoInterval", VAR_SERVER},
{"StrictSubnets", VAR_SERVER | VAR_SAFE},
{"TunnelServer", VAR_SERVER | VAR_SAFE},
{"UDPDiscovery", VAR_SERVER | VAR_SAFE},
{"UDPDiscoveryKeepaliveInterval", VAR_SERVER | VAR_SAFE},
{"UDPDiscoveryInterval", VAR_SERVER | VAR_SAFE},
{"UDPDiscoveryTimeout", VAR_SERVER | VAR_SAFE},
{"MTUInfoInterval", VAR_SERVER | VAR_SAFE},
{"UDPInfoInterval", VAR_SERVER | VAR_SAFE},
{"UDPRcvBuf", VAR_SERVER},
{"UDPSndBuf", VAR_SERVER},
{"UPnP", VAR_SERVER},
@ -1776,12 +1785,12 @@ const var_t variables[] = {
/* Host configuration */
{"Address", VAR_HOST | VAR_MULTIPLE},
{"Cipher", VAR_SERVER | VAR_HOST},
{"ClampMSS", VAR_SERVER | VAR_HOST},
{"Compression", VAR_SERVER | VAR_HOST},
{"ClampMSS", VAR_SERVER | VAR_HOST | VAR_SAFE},
{"Compression", VAR_SERVER | VAR_HOST | VAR_SAFE},
{"Digest", VAR_SERVER | VAR_HOST},
{"Ed25519PublicKey", VAR_HOST},
{"Ed25519PublicKeyFile", VAR_SERVER | VAR_HOST},
{"IndirectData", VAR_SERVER | VAR_HOST},
{"IndirectData", VAR_SERVER | VAR_HOST | VAR_SAFE},
{"MACLength", VAR_SERVER | VAR_HOST},
{"PMTU", VAR_SERVER | VAR_HOST},
{"PMTUDiscovery", VAR_SERVER | VAR_HOST},
@ -1789,7 +1798,7 @@ const var_t variables[] = {
{"PublicKey", VAR_HOST | VAR_OBSOLETE},
{"PublicKeyFile", VAR_SERVER | VAR_HOST | VAR_OBSOLETE},
{"Subnet", VAR_HOST | VAR_MULTIPLE | VAR_SAFE},
{"TCPOnly", VAR_SERVER | VAR_HOST},
{"TCPOnly", VAR_SERVER | VAR_HOST | VAR_SAFE},
{"Weight", VAR_HOST | VAR_SAFE},
{NULL, 0}
};
@ -1880,6 +1889,19 @@ static int cmd_config(int argc, char *argv[]) {
found = true;
variable = (char *)variables[i].name;
if(!strcasecmp(variable, "Subnet")) {
subnet_t s = {0};
if(!str2net(&s, value)) {
fprintf(stderr, "Malformed subnet definition %s\n", value);
}
if(!subnetcheck(s)) {
fprintf(stderr, "Network address and prefix length do not match: %s\n", value);
return 1;
}
}
/* Discourage use of obsolete variables. */
if(variables[i].type & VAR_OBSOLETE && action >= 0) {
@ -2301,6 +2323,7 @@ static int cmd_init(int argc, char *argv[]) {
static int cmd_generate_keys(int argc, char *argv[]) {
#ifdef DISABLE_LEGACY
(void)argv;
if(argc > 1) {
#else
@ -2440,10 +2463,14 @@ static int cmd_edit(int argc, char *argv[]) {
char *command;
#ifndef HAVE_MINGW
const char *editor = getenv("VISUAL");
if (!editor)
if(!editor) {
editor = getenv("EDITOR");
if (!editor)
}
if(!editor) {
editor = "vi";
}
xasprintf(&command, "\"%s\" \"%s\"", editor, filename);
#else

View file

@ -1,7 +1,7 @@
/*
tincd.c -- the main file for tincd
Copyright (C) 1998-2005 Ivo Timmermans
2000-2018 Guus Sliepen <guus@tinc-vpn.org>
2000-2021 Guus Sliepen <guus@tinc-vpn.org>
2008 Max Rijevski <maksuf@gmail.com>
2009 Michael Tokarev <mjt@tls.msk.ru>
2010 Julien Muchembled <jm@jmuchemb.eu>
@ -344,10 +344,15 @@ static bool drop_privs(void) {
# define setpriority(level) !SetPriorityClass(GetCurrentProcess(), (level))
static void stop_handler(void *data, int flags) {
(void)data;
(void)flags;
event_exit();
}
static BOOL WINAPI console_ctrl_handler(DWORD type) {
(void)type;
logger(DEBUG_ALWAYS, LOG_NOTICE, "Got console shutdown request");
if(WSASetEvent(stop_io.event) == FALSE) {
@ -373,7 +378,7 @@ int main(int argc, char **argv) {
if(show_version) {
printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE,
BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR);
printf("Copyright (C) 1998-2018 Ivo Timmermans, Guus Sliepen and others.\n"
printf("Copyright (C) 1998-2021 Ivo Timmermans, Guus Sliepen and others.\n"
"See the AUTHORS file for a complete list.\n\n"
"tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
"and you are welcome to redistribute it under certain conditions;\n"
@ -481,6 +486,8 @@ int main(int argc, char **argv) {
}
int main2(int argc, char **argv) {
(void)argc;
(void)argv;
#endif
char *priority = NULL;

View file

@ -1,6 +1,6 @@
/*
upnp.c -- UPnP-IGD client
Copyright (C) 2015 Guus Sliepen <guus@tinc-vpn.org>,
Copyright (C) 2015-2018 Guus Sliepen <guus@tinc-vpn.org>,
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -19,7 +19,9 @@
#include "upnp.h"
#ifndef HAVE_MINGW
#include <pthread.h>
#endif
#include "miniupnpc/miniupnpc.h"
#include "miniupnpc/upnpcommands.h"
@ -159,7 +161,9 @@ static void *upnp_thread(void *data) {
time_t now = time(NULL);
if(now < refresh_time) {
sleep(refresh_time - now);
nanosleep(&(struct timespec) {
refresh_time - now, 0
}, NULL);
}
}
@ -176,10 +180,20 @@ void upnp_init(bool tcp, bool udp) {
get_config_int(lookup_config(config_tree, "UPnPDiscoverWait"), &upnp_discover_wait);
get_config_int(lookup_config(config_tree, "UPnPRefreshPeriod"), &upnp_refresh_period);
#ifdef HAVE_MINGW
HANDLE handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)upnp_thread, NULL, 0, NULL);
if(!handle) {
logger(DEBUG_ALWAYS, LOG_ERR, "Unable to start UPnP-IGD client thread");
}
#else
pthread_t thread;
int error = pthread_create(&thread, NULL, upnp_thread, NULL);
if(error) {
logger(DEBUG_ALWAYS, LOG_ERR, "Unable to start UPnP-IGD client thread: [%d] %s", error, strerror(error));
}
#endif
}

View file

@ -173,11 +173,7 @@ size_t b64encode_urlsafe(const void *src, char *dst, size_t length) {
return b64encode_internal(src, dst, length, base64_urlsafe);
}
#if defined(HAVE_MINGW) || defined(HAVE_CYGWIN)
#ifdef HAVE_CYGWIN
#include <w32api/windows.h>
#endif
#ifdef HAVE_MINGW
const char *winerror(int err) {
static char buf[1024], *ptr;

View file

@ -53,7 +53,7 @@ static inline void *xrealloc(void *p, size_t n) {
return p;
}
static inline char *xstrdup(const char *s) __attribute__((__malloc__, __nonnull__));
static inline char *xstrdup(const char *s) __attribute__((__malloc__)) __attribute((__nonnull__));
static inline char *xstrdup(const char *s) {
char *p = strdup(s);