Import Upstream version 1.1~pre15
This commit is contained in:
parent
87cef22421
commit
bc8ca65653
85 changed files with 1687 additions and 971 deletions
|
|
@ -1,6 +1,8 @@
|
|||
## Produce this file with automake to get Makefile.in
|
||||
|
||||
sbin_PROGRAMS = tincd tinc sptps_test sptps_keypair
|
||||
sbin_PROGRAMS = tincd tinc
|
||||
check_PROGRAMS = sptps_test sptps_keypair
|
||||
EXTRA_PROGRAMS = sptps_test sptps_keypair
|
||||
|
||||
CLEANFILES = version_git.h
|
||||
|
||||
|
|
@ -18,11 +20,10 @@ version.c: ${srcdir}/version.c
|
|||
endif
|
||||
|
||||
if LINUX
|
||||
sbin_PROGRAMS += sptps_speed
|
||||
EXTRA_PROGRAMS += sptps_speed
|
||||
endif
|
||||
|
||||
ed25519_SOURCES = \
|
||||
ed25519/add_scalar.c \
|
||||
ed25519/ed25519.h \
|
||||
ed25519/fe.c ed25519/fe.h \
|
||||
ed25519/fixedint.h \
|
||||
|
|
@ -41,6 +42,7 @@ chacha_poly1305_SOURCES = \
|
|||
chacha-poly1305/poly1305.c chacha-poly1305/poly1305.h
|
||||
|
||||
tincd_SOURCES = \
|
||||
autoconnect.c autoconnect.h \
|
||||
buffer.c buffer.h \
|
||||
cipher.h \
|
||||
conf.c conf.h \
|
||||
|
|
@ -58,6 +60,7 @@ tincd_SOURCES = \
|
|||
edge.c edge.h \
|
||||
ethernet.h \
|
||||
event.c event.h \
|
||||
fd_device.c \
|
||||
graph.c graph.h \
|
||||
hash.c hash.h \
|
||||
have.h \
|
||||
|
|
|
|||
163
src/Makefile.in
163
src/Makefile.in
|
|
@ -1,7 +1,7 @@
|
|||
# Makefile.in generated by automake 1.15 from Makefile.am.
|
||||
# Makefile.in generated by automake 1.15.1 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1994-2017 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
|
|
@ -88,8 +88,10 @@ PRE_UNINSTALL = :
|
|||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
sbin_PROGRAMS = tincd$(EXEEXT) tinc$(EXEEXT) sptps_test$(EXEEXT) \
|
||||
sptps_keypair$(EXEEXT) $(am__EXEEXT_1)
|
||||
sbin_PROGRAMS = tincd$(EXEEXT) tinc$(EXEEXT)
|
||||
check_PROGRAMS = sptps_test$(EXEEXT) sptps_keypair$(EXEEXT)
|
||||
EXTRA_PROGRAMS = sptps_test$(EXEEXT) sptps_keypair$(EXEEXT) \
|
||||
$(am__EXEEXT_1)
|
||||
@LINUX_TRUE@am__append_1 = sptps_speed
|
||||
@GETOPT_FALSE@am__append_2 = \
|
||||
@GETOPT_FALSE@ getopt.c getopt.h \
|
||||
|
|
@ -216,19 +218,18 @@ CONFIG_CLEAN_VPATH_FILES =
|
|||
am__installdirs = "$(DESTDIR)$(sbindir)"
|
||||
PROGRAMS = $(sbin_PROGRAMS)
|
||||
am__sptps_keypair_SOURCES_DIST = sptps_keypair.c utils.c utils.h \
|
||||
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/ecdsagen.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 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)
|
||||
am__objects_1 = 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)
|
||||
@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)
|
||||
|
|
@ -241,9 +242,9 @@ 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/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/ecdsagen.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 \
|
||||
|
|
@ -272,11 +273,10 @@ 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/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/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 \
|
||||
|
|
@ -300,11 +300,11 @@ am__tinc_SOURCES_DIST = dropin.c dropin.h fsck.c fsck.h ifconfig.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 \
|
||||
ed25519/sc.h ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \
|
||||
ed25519/ecdsa.c ed25519/ecdsagen.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 \
|
||||
|
|
@ -336,23 +336,23 @@ am_tinc_OBJECTS = dropin.$(OBJEXT) fsck.$(OBJEXT) ifconfig.$(OBJEXT) \
|
|||
tinc_OBJECTS = $(am_tinc_OBJECTS)
|
||||
am__DEPENDENCIES_1 =
|
||||
tinc_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
|
||||
am__tincd_SOURCES_DIST = 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 graph.c graph.h hash.c hash.h have.h ipv4.h ipv6.h \
|
||||
list.c list.h logger.c logger.h meta.c meta.h \
|
||||
multicast_device.c names.c names.h net.c net.h net_packet.c \
|
||||
net_setup.c net_socket.c netutl.c netutl.h node.c node.h prf.h \
|
||||
process.c process.h protocol.c protocol.h protocol_auth.c \
|
||||
protocol_edge.c protocol_key.c protocol_misc.c \
|
||||
protocol_subnet.c raw_socket_device.c route.c route.h rsa.h \
|
||||
rsagen.h script.c script.h splay_tree.c splay_tree.h sptps.c \
|
||||
sptps.h subnet.c subnet.h subnet_parse.c system.h tincd.c \
|
||||
utils.c utils.h xalloc.h version.c version.h ed25519/ecdh.c \
|
||||
ed25519/ecdsa.c ed25519/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 \
|
||||
am__tincd_SOURCES_DIST = autoconnect.c autoconnect.h buffer.c buffer.h \
|
||||
cipher.h conf.c conf.h connection.c connection.h control.c \
|
||||
control.h control_common.h crypto.h device.h digest.h dropin.c \
|
||||
dropin.h dummy_device.c ecdh.h ecdsa.h ecdsagen.h edge.c \
|
||||
edge.h ethernet.h event.c event.h fd_device.c graph.c graph.h \
|
||||
hash.c hash.h have.h ipv4.h ipv6.h list.c list.h logger.c \
|
||||
logger.h meta.c meta.h multicast_device.c names.c names.h \
|
||||
net.c net.h net_packet.c net_setup.c net_socket.c netutl.c \
|
||||
netutl.h node.c node.h prf.h process.c process.h protocol.c \
|
||||
protocol.h protocol_auth.c protocol_edge.c protocol_key.c \
|
||||
protocol_misc.c protocol_subnet.c raw_socket_device.c route.c \
|
||||
route.h rsa.h rsagen.h script.c script.h splay_tree.c \
|
||||
splay_tree.h sptps.c sptps.h subnet.c subnet.h subnet_parse.c \
|
||||
system.h tincd.c utils.c utils.h xalloc.h version.c version.h \
|
||||
ed25519/ecdh.c ed25519/ecdsa.c ed25519/ed25519.h ed25519/fe.c \
|
||||
ed25519/fe.h ed25519/fixedint.h ed25519/ge.c ed25519/ge.h \
|
||||
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 \
|
||||
|
|
@ -384,14 +384,15 @@ am__tincd_SOURCES_DIST = buffer.c buffer.h cipher.h conf.c conf.h \
|
|||
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/prf.$(OBJEXT) \
|
||||
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/rsa.$(OBJEXT)
|
||||
@MINIUPNPC_TRUE@am__objects_23 = upnp.$(OBJEXT)
|
||||
am_tincd_OBJECTS = buffer.$(OBJEXT) conf.$(OBJEXT) \
|
||||
connection.$(OBJEXT) control.$(OBJEXT) dropin.$(OBJEXT) \
|
||||
dummy_device.$(OBJEXT) edge.$(OBJEXT) event.$(OBJEXT) \
|
||||
graph.$(OBJEXT) hash.$(OBJEXT) list.$(OBJEXT) logger.$(OBJEXT) \
|
||||
meta.$(OBJEXT) multicast_device.$(OBJEXT) names.$(OBJEXT) \
|
||||
net.$(OBJEXT) net_packet.$(OBJEXT) net_setup.$(OBJEXT) \
|
||||
net_socket.$(OBJEXT) netutl.$(OBJEXT) node.$(OBJEXT) \
|
||||
process.$(OBJEXT) protocol.$(OBJEXT) protocol_auth.$(OBJEXT) \
|
||||
am_tincd_OBJECTS = autoconnect.$(OBJEXT) buffer.$(OBJEXT) \
|
||||
conf.$(OBJEXT) connection.$(OBJEXT) control.$(OBJEXT) \
|
||||
dropin.$(OBJEXT) dummy_device.$(OBJEXT) edge.$(OBJEXT) \
|
||||
event.$(OBJEXT) fd_device.$(OBJEXT) graph.$(OBJEXT) \
|
||||
hash.$(OBJEXT) list.$(OBJEXT) logger.$(OBJEXT) meta.$(OBJEXT) \
|
||||
multicast_device.$(OBJEXT) names.$(OBJEXT) net.$(OBJEXT) \
|
||||
net_packet.$(OBJEXT) net_setup.$(OBJEXT) net_socket.$(OBJEXT) \
|
||||
netutl.$(OBJEXT) node.$(OBJEXT) process.$(OBJEXT) \
|
||||
protocol.$(OBJEXT) protocol_auth.$(OBJEXT) \
|
||||
protocol_edge.$(OBJEXT) protocol_key.$(OBJEXT) \
|
||||
protocol_misc.$(OBJEXT) protocol_subnet.$(OBJEXT) \
|
||||
raw_socket_device.$(OBJEXT) route.$(OBJEXT) script.$(OBJEXT) \
|
||||
|
|
@ -570,7 +571,6 @@ top_builddir = @top_builddir@
|
|||
top_srcdir = @top_srcdir@
|
||||
CLEANFILES = version_git.h
|
||||
ed25519_SOURCES = \
|
||||
ed25519/add_scalar.c \
|
||||
ed25519/ed25519.h \
|
||||
ed25519/fe.c ed25519/fe.h \
|
||||
ed25519/fixedint.h \
|
||||
|
|
@ -588,16 +588,16 @@ chacha_poly1305_SOURCES = \
|
|||
chacha-poly1305/chacha-poly1305.c chacha-poly1305/chacha-poly1305.h \
|
||||
chacha-poly1305/poly1305.c chacha-poly1305/poly1305.h
|
||||
|
||||
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 \
|
||||
graph.c graph.h hash.c hash.h have.h ipv4.h ipv6.h list.c \
|
||||
list.h logger.c logger.h meta.c meta.h multicast_device.c \
|
||||
names.c names.h net.c net.h net_packet.c net_setup.c \
|
||||
net_socket.c netutl.c netutl.h node.c node.h prf.h process.c \
|
||||
process.h protocol.c protocol.h protocol_auth.c \
|
||||
protocol_edge.c protocol_key.c protocol_misc.c \
|
||||
tincd_SOURCES = autoconnect.c autoconnect.h buffer.c buffer.h cipher.h \
|
||||
conf.c conf.h connection.c connection.h control.c control.h \
|
||||
control_common.h crypto.h device.h digest.h dropin.c dropin.h \
|
||||
dummy_device.c ecdh.h ecdsa.h ecdsagen.h edge.c edge.h \
|
||||
ethernet.h event.c event.h fd_device.c graph.c graph.h hash.c \
|
||||
hash.h have.h ipv4.h ipv6.h list.c list.h logger.c logger.h \
|
||||
meta.c meta.h multicast_device.c names.c names.h net.c net.h \
|
||||
net_packet.c net_setup.c net_socket.c netutl.c netutl.h node.c \
|
||||
node.h prf.h process.c process.h protocol.c protocol.h \
|
||||
protocol_auth.c protocol_edge.c protocol_key.c protocol_misc.c \
|
||||
protocol_subnet.c raw_socket_device.c route.c route.h rsa.h \
|
||||
rsagen.h script.c script.h splay_tree.c splay_tree.h sptps.c \
|
||||
sptps.h subnet.c subnet.h subnet_parse.c system.h tincd.c \
|
||||
|
|
@ -666,6 +666,9 @@ $(top_srcdir)/configure: $(am__configure_deps)
|
|||
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(am__aclocal_m4_deps):
|
||||
|
||||
clean-checkPROGRAMS:
|
||||
-test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS)
|
||||
install-sbinPROGRAMS: $(sbin_PROGRAMS)
|
||||
@$(NORMAL_INSTALL)
|
||||
@list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
|
||||
|
|
@ -732,8 +735,6 @@ ed25519/$(DEPDIR)/$(am__dirstamp):
|
|||
@: > 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) \
|
||||
ed25519/$(DEPDIR)/$(am__dirstamp)
|
||||
ed25519/ge.$(OBJEXT): ed25519/$(am__dirstamp) \
|
||||
|
|
@ -892,6 +893,7 @@ mostlyclean-compile:
|
|||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/autoconnect.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buffer.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conf.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connection.Po@am__quote@
|
||||
|
|
@ -900,6 +902,7 @@ 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)/fd_device.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsck.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@
|
||||
|
|
@ -950,7 +953,6 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/chacha.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/poly1305.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@cygwin/$(DEPDIR)/device.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/add_scalar.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdh.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdsa.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdsagen.Po@am__quote@
|
||||
|
|
@ -1079,6 +1081,7 @@ distdir: $(DISTFILES)
|
|||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
|
||||
check: check-am
|
||||
all-am: Makefile $(PROGRAMS)
|
||||
installdirs:
|
||||
|
|
@ -1138,7 +1141,8 @@ maintainer-clean-generic:
|
|||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic clean-sbinPROGRAMS mostlyclean-am
|
||||
clean-am: clean-checkPROGRAMS clean-generic clean-sbinPROGRAMS \
|
||||
mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -rf ./$(DEPDIR) bsd/$(DEPDIR) chacha-poly1305/$(DEPDIR) cygwin/$(DEPDIR) ed25519/$(DEPDIR) gcrypt/$(DEPDIR) linux/$(DEPDIR) mingw/$(DEPDIR) nolegacy/$(DEPDIR) openssl/$(DEPDIR) solaris/$(DEPDIR)
|
||||
|
|
@ -1205,21 +1209,22 @@ ps-am:
|
|||
|
||||
uninstall-am: uninstall-sbinPROGRAMS
|
||||
|
||||
.MAKE: install-am install-strip
|
||||
.MAKE: check-am install-am install-strip
|
||||
|
||||
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
|
||||
clean-sbinPROGRAMS cscopelist-am ctags ctags-am distclean \
|
||||
distclean-compile distclean-generic distclean-tags distdir dvi \
|
||||
dvi-am html html-am info info-am install install-am \
|
||||
install-data install-data-am install-dvi install-dvi-am \
|
||||
install-exec install-exec-am install-html install-html-am \
|
||||
install-info install-info-am install-man install-pdf \
|
||||
install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \
|
||||
install-strip installcheck installcheck-am \
|
||||
installcheck-sbinPROGRAMS installdirs maintainer-clean \
|
||||
maintainer-clean-generic mostlyclean mostlyclean-compile \
|
||||
mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \
|
||||
uninstall-am uninstall-sbinPROGRAMS
|
||||
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \
|
||||
clean-checkPROGRAMS clean-generic clean-sbinPROGRAMS \
|
||||
cscopelist-am ctags ctags-am distclean distclean-compile \
|
||||
distclean-generic distclean-tags distdir dvi dvi-am html \
|
||||
html-am info info-am install install-am install-data \
|
||||
install-data-am install-dvi install-dvi-am install-exec \
|
||||
install-exec-am install-html install-html-am install-info \
|
||||
install-info-am install-man install-pdf install-pdf-am \
|
||||
install-ps install-ps-am install-sbinPROGRAMS install-strip \
|
||||
installcheck installcheck-am installcheck-sbinPROGRAMS \
|
||||
installdirs maintainer-clean maintainer-clean-generic \
|
||||
mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \
|
||||
ps ps-am tags tags-am uninstall uninstall-am \
|
||||
uninstall-sbinPROGRAMS
|
||||
|
||||
.PRECIOUS: Makefile
|
||||
|
||||
|
|
|
|||
174
src/autoconnect.c
Normal file
174
src/autoconnect.c
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
/*
|
||||
autoconnect.c -- automatic connection establishment
|
||||
Copyright (C) 2017 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 "connection.h"
|
||||
#include "logger.h"
|
||||
#include "node.h"
|
||||
#include "xalloc.h"
|
||||
|
||||
static void make_new_connection() {
|
||||
/* Select a random node we haven't connected to yet. */
|
||||
int count = 0;
|
||||
for splay_each(node_t, n, node_tree) {
|
||||
if(n == myself || n->connection || !(n->status.has_address || n->status.reachable))
|
||||
continue;
|
||||
count++;
|
||||
}
|
||||
|
||||
if(!count)
|
||||
return;
|
||||
|
||||
int r = rand() % count;
|
||||
|
||||
for splay_each(node_t, n, node_tree) {
|
||||
if(n == myself || n->connection || !(n->status.has_address || n->status.reachable))
|
||||
continue;
|
||||
|
||||
if(r--)
|
||||
continue;
|
||||
|
||||
bool found = false;
|
||||
|
||||
for list_each(outgoing_t, outgoing, outgoing_list) {
|
||||
if(!strcmp(outgoing->name, n->name)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!found) {
|
||||
logger(DEBUG_CONNECTIONS, LOG_INFO, "Autoconnecting to %s", n->name);
|
||||
outgoing_t *outgoing = xzalloc(sizeof *outgoing);
|
||||
outgoing->name = xstrdup(n->name);
|
||||
list_insert_tail(outgoing_list, outgoing);
|
||||
setup_outgoing_connection(outgoing);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void connect_to_unreachable() {
|
||||
/* Select a random known node. The rationale is that if there are many
|
||||
* reachable nodes, and only a few unreachable nodes, we don't want all
|
||||
* reachable nodes to try to connect to the unreachable ones at the
|
||||
* same time. This way, we back off automatically. Conversely, if there
|
||||
* are only a few reachable nodes, and many unreachable ones, we're
|
||||
* going to try harder to connect to them. */
|
||||
|
||||
int r = rand() % node_tree->count;
|
||||
|
||||
for splay_each(node_t, n, node_tree) {
|
||||
if(r--)
|
||||
continue;
|
||||
|
||||
/* Is it unreachable and do we know an address for it? If not, return. */
|
||||
if(n == myself || n->connection || n->status.reachable || !n->status.has_address)
|
||||
return;
|
||||
|
||||
/* Are we already trying to make an outgoing connection to it? If not, return. */
|
||||
for list_each(outgoing_t, outgoing, outgoing_list)
|
||||
if(!strcmp(outgoing->name, n->name))
|
||||
return;
|
||||
|
||||
logger(DEBUG_CONNECTIONS, LOG_INFO, "Autoconnecting to %s", n->name);
|
||||
outgoing_t *outgoing = xzalloc(sizeof *outgoing);
|
||||
outgoing->name = xstrdup(n->name);
|
||||
list_insert_tail(outgoing_list, outgoing);
|
||||
setup_outgoing_connection(outgoing);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void drop_superfluous_outgoing_connection() {
|
||||
/* Choose a random outgoing connection to a node that has at least one other connection. */
|
||||
int count = 0;
|
||||
for list_each(connection_t, c, connection_list) {
|
||||
if(!c->edge || !c->outgoing || !c->node || c->node->edge_tree->count < 2)
|
||||
continue;
|
||||
count++;
|
||||
}
|
||||
|
||||
if(!count)
|
||||
return;
|
||||
|
||||
int r = rand() % count;
|
||||
|
||||
for list_each(connection_t, c, connection_list) {
|
||||
if(!c->edge || !c->outgoing || !c->node || c->node->edge_tree->count < 2)
|
||||
continue;
|
||||
|
||||
if(r--)
|
||||
continue;
|
||||
|
||||
logger(DEBUG_CONNECTIONS, LOG_INFO, "Autodisconnecting from %s", c->name);
|
||||
list_delete(outgoing_list, c->outgoing);
|
||||
c->outgoing = NULL;
|
||||
terminate_connection(c, c->edge);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void drop_superfluous_pending_connections() {
|
||||
for list_each(outgoing_t, o, outgoing_list) {
|
||||
/* Only look for connections that are waiting to be retried later. */
|
||||
bool found = false;
|
||||
for list_each(connection_t, c, connection_list) {
|
||||
if(c->outgoing == o) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(found)
|
||||
continue;
|
||||
|
||||
logger(DEBUG_CONNECTIONS, LOG_INFO, "Cancelled outgoing connection to %s", o->name);
|
||||
list_delete_node(outgoing_list, node);
|
||||
}
|
||||
}
|
||||
|
||||
void do_autoconnect() {
|
||||
/* Count number of active connections. */
|
||||
int nc = 0;
|
||||
for list_each(connection_t, c, connection_list) {
|
||||
if(c->edge)
|
||||
nc++;
|
||||
}
|
||||
|
||||
/* Less than 3 connections? Eagerly try to make a new one. */
|
||||
if(nc < 3) {
|
||||
make_new_connection();
|
||||
return;
|
||||
}
|
||||
|
||||
/* More than 3 connections? See if we can get rid of a superfluous one. */
|
||||
if(nc > 3)
|
||||
drop_superfluous_outgoing_connection();
|
||||
|
||||
|
||||
/* 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();
|
||||
}
|
||||
25
src/autoconnect.h
Normal file
25
src/autoconnect.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
autoconnect.h -- header for autoconnect.c
|
||||
Copyright (C) 2017 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_AUTOCONNECT_H__
|
||||
#define __TINC_AUTOCONNECT_H__
|
||||
|
||||
extern void do_autoconnect(void);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
device.c -- Interaction BSD tun/tap device
|
||||
Copyright (C) 2001-2005 Ivo Timmermans,
|
||||
2001-2016 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2001-2017 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2009 Grzegorz Dymarek <gregd72002@googlemail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
|
@ -198,18 +198,19 @@ static bool setup_device(void) {
|
|||
|
||||
// Guess what the corresponding interface is called
|
||||
|
||||
char *realname;
|
||||
char *realname = NULL;
|
||||
|
||||
#if defined(HAVE_FDEVNAME)
|
||||
realname = fdevname(device_fd) ? : device;
|
||||
realname = fdevname(device_fd);
|
||||
#elif defined(HAVE_DEVNAME)
|
||||
struct stat buf;
|
||||
if(!fstat(device_fd, &buf))
|
||||
realname = devname(buf.st_rdev, S_IFCHR) ? : device;
|
||||
#else
|
||||
realname = device;
|
||||
realname = devname(buf.st_rdev, S_IFCHR);
|
||||
#endif
|
||||
|
||||
if(!realname)
|
||||
realname = device;
|
||||
|
||||
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))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
cipher.h -- header file cipher.c
|
||||
Copyright (C) 2007-2013 Guus Sliepen <guus@tinc-vpn.org>
|
||||
Copyright (C) 2007-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
|
||||
|
|
@ -30,10 +30,10 @@ typedef struct cipher cipher_t;
|
|||
|
||||
extern cipher_t *cipher_open_by_name(const char *) __attribute__ ((__malloc__));
|
||||
extern cipher_t *cipher_open_by_nid(int) __attribute__ ((__malloc__));
|
||||
extern 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 uint64_t cipher_budget(const cipher_t *);
|
||||
extern void cipher_get_key(const cipher_t *, void *);
|
||||
extern bool cipher_set_key(cipher_t *, void *, bool) __attribute__ ((__warn_unused_result__));
|
||||
extern bool cipher_set_key_from_rsa(cipher_t *, void *, size_t, bool) __attribute__ ((__warn_unused_result__));
|
||||
|
|
|
|||
|
|
@ -81,6 +81,8 @@ typedef struct connection_t {
|
|||
cipher_t *outcipher; /* Cipher we will use to send data to him */
|
||||
digest_t *indigest;
|
||||
digest_t *outdigest;
|
||||
uint64_t inbudget;
|
||||
uint64_t outbudget;
|
||||
#endif
|
||||
|
||||
ecdsa_t *ecdsa; /* his public ECDSA key */
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ extern const devops_t os_devops;
|
|||
extern const devops_t dummy_devops;
|
||||
extern const devops_t raw_socket_devops;
|
||||
extern const devops_t multicast_devops;
|
||||
extern const devops_t fd_devops;
|
||||
extern const devops_t uml_devops;
|
||||
extern const devops_t vde_devops;
|
||||
extern devops_t devops;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
digest.h -- header file digest.c
|
||||
Copyright (C) 2007-2013 Guus Sliepen <guus@tinc-vpn.org>
|
||||
Copyright (C) 2007-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
|
||||
|
|
@ -28,7 +28,6 @@ typedef struct digest digest_t;
|
|||
|
||||
extern digest_t *digest_open_by_name(const char *name, int maclength) __attribute__ ((__malloc__));
|
||||
extern digest_t *digest_open_by_nid(int nid, int maclength) __attribute__ ((__malloc__));
|
||||
extern digest_t *digest_open_sha1(int maclength) __attribute__ ((__malloc__));
|
||||
extern void digest_close(digest_t *);
|
||||
extern bool digest_create(digest_t *, const void *indata, size_t inlen, void *outdata) __attribute__ ((__warn_unused_result__));
|
||||
extern bool digest_verify(digest_t *, const void *indata, size_t inlen, const void *digestdata) __attribute__ ((__warn_unused_result__));
|
||||
|
|
|
|||
|
|
@ -106,14 +106,13 @@ int vasprintf(char **buf, const char *fmt, va_list ap) {
|
|||
|
||||
va_copy(aq, ap);
|
||||
status = vsnprintf(*buf, len, fmt, aq);
|
||||
buf[len - 1] = 0;
|
||||
va_end(aq);
|
||||
|
||||
if(status >= 0)
|
||||
*buf = xrealloc(*buf, status + 1);
|
||||
|
||||
if(status > len - 1) {
|
||||
len = status;
|
||||
len = status + 1;
|
||||
va_copy(aq, ap);
|
||||
status = vsnprintf(*buf, len, fmt, aq);
|
||||
va_end(aq);
|
||||
|
|
|
|||
|
|
@ -1,56 +0,0 @@
|
|||
#include "ed25519.h"
|
||||
#include "ge.h"
|
||||
#include "sc.h"
|
||||
|
||||
|
||||
/* see http://crypto.stackexchange.com/a/6215/4697 */
|
||||
void ed25519_add_scalar(unsigned char *public_key, unsigned char *private_key, const unsigned char *scalar) {
|
||||
const unsigned char SC_1[32] = {1}; /* scalar with value 1 */
|
||||
|
||||
unsigned char n[32];
|
||||
ge_p3 nB;
|
||||
ge_p1p1 A_p1p1;
|
||||
ge_p3 A;
|
||||
ge_p3 public_key_unpacked;
|
||||
ge_cached T;
|
||||
|
||||
int i;
|
||||
|
||||
/* copy the scalar and clear highest bit */
|
||||
for (i = 0; i < 31; ++i) {
|
||||
n[i] = scalar[i];
|
||||
}
|
||||
n[31] = scalar[31] & 127;
|
||||
|
||||
/* private key: a = n + t */
|
||||
if (private_key) {
|
||||
sc_muladd(private_key, SC_1, n, private_key);
|
||||
}
|
||||
|
||||
/* public key: A = nB + T */
|
||||
if (public_key) {
|
||||
/* if we know the private key we don't need a point addition, which is faster */
|
||||
/* using a "timing attack" you could find out wether or not we know the private
|
||||
key, but this information seems rather useless - if this is important pass
|
||||
public_key and private_key seperately in 2 function calls */
|
||||
if (private_key) {
|
||||
ge_scalarmult_base(&A, private_key);
|
||||
} else {
|
||||
/* unpack public key into T */
|
||||
ge_frombytes_negate_vartime(&public_key_unpacked, public_key);
|
||||
fe_neg(public_key_unpacked.X, public_key_unpacked.X); // undo negate
|
||||
fe_neg(public_key_unpacked.T, public_key_unpacked.T); // undo negate
|
||||
ge_p3_to_cached(&T, &public_key_unpacked);
|
||||
|
||||
/* calculate n*B */
|
||||
ge_scalarmult_base(&nB, n);
|
||||
|
||||
/* A = n*B + T */
|
||||
ge_add(&A_p1p1, &nB, &T);
|
||||
ge_p1p1_to_p3(&A, &A_p1p1);
|
||||
}
|
||||
|
||||
/* pack public key */
|
||||
ge_p3_tobytes(public_key, &A);
|
||||
}
|
||||
}
|
||||
|
|
@ -27,7 +27,6 @@ int ED25519_DECLSPEC ed25519_create_seed(unsigned char *seed);
|
|||
void ED25519_DECLSPEC ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, const unsigned char *seed);
|
||||
void ED25519_DECLSPEC ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key, const unsigned char *private_key);
|
||||
int ED25519_DECLSPEC ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *private_key);
|
||||
void ED25519_DECLSPEC ed25519_add_scalar(unsigned char *public_key, unsigned char *private_key, const unsigned char *scalar);
|
||||
void ED25519_DECLSPEC ed25519_key_exchange(unsigned char *shared_secret, const unsigned char *public_key, const unsigned char *private_key);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -81,42 +81,36 @@ void sc_reduce(unsigned char *s) {
|
|||
s14 -= s23 * 997805;
|
||||
s15 += s23 * 136657;
|
||||
s16 -= s23 * 683901;
|
||||
s23 = 0;
|
||||
s10 += s22 * 666643;
|
||||
s11 += s22 * 470296;
|
||||
s12 += s22 * 654183;
|
||||
s13 -= s22 * 997805;
|
||||
s14 += s22 * 136657;
|
||||
s15 -= s22 * 683901;
|
||||
s22 = 0;
|
||||
s9 += s21 * 666643;
|
||||
s10 += s21 * 470296;
|
||||
s11 += s21 * 654183;
|
||||
s12 -= s21 * 997805;
|
||||
s13 += s21 * 136657;
|
||||
s14 -= s21 * 683901;
|
||||
s21 = 0;
|
||||
s8 += s20 * 666643;
|
||||
s9 += s20 * 470296;
|
||||
s10 += s20 * 654183;
|
||||
s11 -= s20 * 997805;
|
||||
s12 += s20 * 136657;
|
||||
s13 -= s20 * 683901;
|
||||
s20 = 0;
|
||||
s7 += s19 * 666643;
|
||||
s8 += s19 * 470296;
|
||||
s9 += s19 * 654183;
|
||||
s10 -= s19 * 997805;
|
||||
s11 += s19 * 136657;
|
||||
s12 -= s19 * 683901;
|
||||
s19 = 0;
|
||||
s6 += s18 * 666643;
|
||||
s7 += s18 * 470296;
|
||||
s8 += s18 * 654183;
|
||||
s9 -= s18 * 997805;
|
||||
s10 += s18 * 136657;
|
||||
s11 -= s18 * 683901;
|
||||
s18 = 0;
|
||||
carry6 = (s6 + (1 << 20)) >> 21;
|
||||
s7 += carry6;
|
||||
s6 -= shl64(carry6, 21);
|
||||
|
|
@ -156,35 +150,30 @@ void sc_reduce(unsigned char *s) {
|
|||
s8 -= s17 * 997805;
|
||||
s9 += s17 * 136657;
|
||||
s10 -= s17 * 683901;
|
||||
s17 = 0;
|
||||
s4 += s16 * 666643;
|
||||
s5 += s16 * 470296;
|
||||
s6 += s16 * 654183;
|
||||
s7 -= s16 * 997805;
|
||||
s8 += s16 * 136657;
|
||||
s9 -= s16 * 683901;
|
||||
s16 = 0;
|
||||
s3 += s15 * 666643;
|
||||
s4 += s15 * 470296;
|
||||
s5 += s15 * 654183;
|
||||
s6 -= s15 * 997805;
|
||||
s7 += s15 * 136657;
|
||||
s8 -= s15 * 683901;
|
||||
s15 = 0;
|
||||
s2 += s14 * 666643;
|
||||
s3 += s14 * 470296;
|
||||
s4 += s14 * 654183;
|
||||
s5 -= s14 * 997805;
|
||||
s6 += s14 * 136657;
|
||||
s7 -= s14 * 683901;
|
||||
s14 = 0;
|
||||
s1 += s13 * 666643;
|
||||
s2 += s13 * 470296;
|
||||
s3 += s13 * 654183;
|
||||
s4 -= s13 * 997805;
|
||||
s5 += s13 * 136657;
|
||||
s6 -= s13 * 683901;
|
||||
s13 = 0;
|
||||
s0 += s12 * 666643;
|
||||
s1 += s12 * 470296;
|
||||
s2 += s12 * 654183;
|
||||
|
|
@ -277,7 +266,6 @@ void sc_reduce(unsigned char *s) {
|
|||
s3 -= s12 * 997805;
|
||||
s4 += s12 * 136657;
|
||||
s5 -= s12 * 683901;
|
||||
s12 = 0;
|
||||
carry0 = s0 >> 21;
|
||||
s1 += carry0;
|
||||
s0 -= shl64(carry0, 21);
|
||||
|
|
@ -543,42 +531,36 @@ void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b,
|
|||
s14 -= s23 * 997805;
|
||||
s15 += s23 * 136657;
|
||||
s16 -= s23 * 683901;
|
||||
s23 = 0;
|
||||
s10 += s22 * 666643;
|
||||
s11 += s22 * 470296;
|
||||
s12 += s22 * 654183;
|
||||
s13 -= s22 * 997805;
|
||||
s14 += s22 * 136657;
|
||||
s15 -= s22 * 683901;
|
||||
s22 = 0;
|
||||
s9 += s21 * 666643;
|
||||
s10 += s21 * 470296;
|
||||
s11 += s21 * 654183;
|
||||
s12 -= s21 * 997805;
|
||||
s13 += s21 * 136657;
|
||||
s14 -= s21 * 683901;
|
||||
s21 = 0;
|
||||
s8 += s20 * 666643;
|
||||
s9 += s20 * 470296;
|
||||
s10 += s20 * 654183;
|
||||
s11 -= s20 * 997805;
|
||||
s12 += s20 * 136657;
|
||||
s13 -= s20 * 683901;
|
||||
s20 = 0;
|
||||
s7 += s19 * 666643;
|
||||
s8 += s19 * 470296;
|
||||
s9 += s19 * 654183;
|
||||
s10 -= s19 * 997805;
|
||||
s11 += s19 * 136657;
|
||||
s12 -= s19 * 683901;
|
||||
s19 = 0;
|
||||
s6 += s18 * 666643;
|
||||
s7 += s18 * 470296;
|
||||
s8 += s18 * 654183;
|
||||
s9 -= s18 * 997805;
|
||||
s10 += s18 * 136657;
|
||||
s11 -= s18 * 683901;
|
||||
s18 = 0;
|
||||
carry6 = (s6 + (1 << 20)) >> 21;
|
||||
s7 += carry6;
|
||||
s6 -= shl64(carry6, 21);
|
||||
|
|
@ -618,35 +600,30 @@ void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b,
|
|||
s8 -= s17 * 997805;
|
||||
s9 += s17 * 136657;
|
||||
s10 -= s17 * 683901;
|
||||
s17 = 0;
|
||||
s4 += s16 * 666643;
|
||||
s5 += s16 * 470296;
|
||||
s6 += s16 * 654183;
|
||||
s7 -= s16 * 997805;
|
||||
s8 += s16 * 136657;
|
||||
s9 -= s16 * 683901;
|
||||
s16 = 0;
|
||||
s3 += s15 * 666643;
|
||||
s4 += s15 * 470296;
|
||||
s5 += s15 * 654183;
|
||||
s6 -= s15 * 997805;
|
||||
s7 += s15 * 136657;
|
||||
s8 -= s15 * 683901;
|
||||
s15 = 0;
|
||||
s2 += s14 * 666643;
|
||||
s3 += s14 * 470296;
|
||||
s4 += s14 * 654183;
|
||||
s5 -= s14 * 997805;
|
||||
s6 += s14 * 136657;
|
||||
s7 -= s14 * 683901;
|
||||
s14 = 0;
|
||||
s1 += s13 * 666643;
|
||||
s2 += s13 * 470296;
|
||||
s3 += s13 * 654183;
|
||||
s4 -= s13 * 997805;
|
||||
s5 += s13 * 136657;
|
||||
s6 -= s13 * 683901;
|
||||
s13 = 0;
|
||||
s0 += s12 * 666643;
|
||||
s1 += s12 * 470296;
|
||||
s2 += s12 * 654183;
|
||||
|
|
@ -739,7 +716,6 @@ void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b,
|
|||
s3 -= s12 * 997805;
|
||||
s4 += s12 * 136657;
|
||||
s5 -= s12 * 683901;
|
||||
s12 = 0;
|
||||
carry0 = s0 >> 21;
|
||||
s1 += carry0;
|
||||
s0 -= shl64(carry0, 21);
|
||||
|
|
|
|||
|
|
@ -25,6 +25,15 @@
|
|||
#define ETH_ALEN 6
|
||||
#endif
|
||||
|
||||
#ifndef ETH_HLEN
|
||||
#define ETH_HLEN 14
|
||||
#endif
|
||||
|
||||
#ifndef ETHER_TYPE_LEN
|
||||
#define ETHER_TYPE_LEN 2
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef ARPHRD_ETHER
|
||||
#define ARPHRD_ETHER 1
|
||||
#endif
|
||||
|
|
@ -45,6 +54,10 @@
|
|||
#define ETH_P_8021Q 0x8100
|
||||
#endif
|
||||
|
||||
#ifndef ETH_P_MAX
|
||||
#define ETH_P_MAX 0xFFFF
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_ETHER_HEADER
|
||||
struct ether_header {
|
||||
uint8_t ether_dhost[ETH_ALEN];
|
||||
|
|
|
|||
|
|
@ -357,10 +357,13 @@ bool event_loop(void) {
|
|||
WSANETWORKEVENTS network_events;
|
||||
if (WSAEnumNetworkEvents(io->fd, io->event, &network_events) != 0)
|
||||
return false;
|
||||
if (network_events.lNetworkEvents & WRITE_EVENTS)
|
||||
io->cb(io->data, IO_WRITE);
|
||||
if (network_events.lNetworkEvents & READ_EVENTS)
|
||||
io->cb(io->data, IO_READ);
|
||||
/*
|
||||
The fd might be available for write too. However, if we already fired the read callback, that
|
||||
callback might have deleted the io (e.g. through terminate_connection()), so we can't fire the
|
||||
write callback here. Instead, we loop back and let the writable io loop above handle it.
|
||||
*/
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
123
src/fd_device.c
Normal file
123
src/fd_device.c
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
fd_device.c -- Interaction with Android tun fd
|
||||
Copyright (C) 2001-2005 Ivo Timmermans,
|
||||
2001-2016 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2009 Grzegorz Dymarek <gregd72002@googlemail.com>
|
||||
2016 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
|
||||
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 "device.h"
|
||||
#include "ethernet.h"
|
||||
#include "logger.h"
|
||||
#include "net.h"
|
||||
#include "route.h"
|
||||
#include "utils.h"
|
||||
|
||||
static inline bool check_config(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!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool setup_device(void) {
|
||||
if(!check_config()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(device_fd < 0) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s!", device, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
logger(DEBUG_ALWAYS, LOG_INFO, "fd/%d adapter set up.", device_fd);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void close_device(void) {
|
||||
close(device_fd);
|
||||
device_fd = -1;
|
||||
}
|
||||
|
||||
static inline uint16_t get_ip_ethertype(vpn_packet_t *packet) {
|
||||
switch (DATA(packet)[ETH_HLEN] >> 4) {
|
||||
case 4:
|
||||
return ETH_P_IP;
|
||||
|
||||
case 6:
|
||||
return ETH_P_IPV6;
|
||||
|
||||
default:
|
||||
return ETH_P_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void set_etherheader(vpn_packet_t *packet, uint16_t ethertype) {
|
||||
memset(DATA(packet), 0, ETH_HLEN - ETHER_TYPE_LEN);
|
||||
|
||||
DATA(packet)[ETH_HLEN - ETHER_TYPE_LEN] = (ethertype >> 8) & 0xFF;
|
||||
DATA(packet)[ETH_HLEN - ETHER_TYPE_LEN + 1] = ethertype & 0xFF;
|
||||
}
|
||||
|
||||
static bool read_packet(vpn_packet_t *packet) {
|
||||
int lenin = read(device_fd, DATA(packet) + ETH_HLEN, MTU - ETH_HLEN);
|
||||
if(lenin <= 0) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from fd/%d: %s!", device_fd, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t ethertype = get_ip_ethertype(packet);
|
||||
if(ethertype == ETH_P_MAX) {
|
||||
logger(DEBUG_TRAFFIC, LOG_ERR, "Unknown IP version while reading packet from fd/%d!", device_fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
set_etherheader(packet, ethertype);
|
||||
packet->len = lenin + ETH_HLEN;
|
||||
|
||||
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from fd/%d.", packet->len, device_fd);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool write_packet(vpn_packet_t *packet) {
|
||||
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to fd/%d.", packet->len, device_fd);
|
||||
|
||||
if(write(device_fd, DATA(packet) + ETH_HLEN, packet->len - ETH_HLEN) < 0) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to fd/%d: %s!", device_fd, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const devops_t fd_devops = {
|
||||
.setup = setup_device,
|
||||
.close = close_device,
|
||||
.read = read_packet,
|
||||
.write = write_packet,
|
||||
};
|
||||
|
|
@ -297,9 +297,10 @@ int fsck(const char *argv0) {
|
|||
rsa_t *rsa_pub = NULL;
|
||||
|
||||
f = fopen(fname, "r");
|
||||
if(f)
|
||||
if(f) {
|
||||
rsa_pub = rsa_read_pem_public_key(f);
|
||||
fclose(f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
if(rsa_priv) {
|
||||
if(!rsa_pub) {
|
||||
|
|
@ -352,12 +353,12 @@ int fsck(const char *argv0) {
|
|||
f = fopen(fname, "r");
|
||||
if(f) {
|
||||
ecdsa_pub = get_pubkey(f);
|
||||
if(!f) {
|
||||
if(!ecdsa_pub) {
|
||||
rewind(f);
|
||||
ecdsa_pub = ecdsa_read_pem_public_key(f);
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
if(ecdsa_priv) {
|
||||
if(!ecdsa_pub) {
|
||||
|
|
|
|||
23
src/graph.c
23
src/graph.c
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
graph.c -- graph algorithms
|
||||
Copyright (C) 2001-2013 Guus Sliepen <guus@tinc-vpn.org>,
|
||||
Copyright (C) 2001-2017 Guus Sliepen <guus@tinc-vpn.org>,
|
||||
2001-2005 Ivo Timmermans
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
|
@ -247,28 +247,23 @@ static void check_reachability(void) {
|
|||
char *name;
|
||||
char *address;
|
||||
char *port;
|
||||
char *envp[8] = {NULL};
|
||||
|
||||
xasprintf(&envp[0], "NETNAME=%s", netname ? : "");
|
||||
xasprintf(&envp[1], "DEVICE=%s", device ? : "");
|
||||
xasprintf(&envp[2], "INTERFACE=%s", iface ? : "");
|
||||
xasprintf(&envp[3], "NODE=%s", n->name);
|
||||
environment_t env;
|
||||
environment_init(&env);
|
||||
environment_add(&env, "NODE=%s", n->name);
|
||||
sockaddr2str(&n->address, &address, &port);
|
||||
xasprintf(&envp[4], "REMOTEADDRESS=%s", address);
|
||||
xasprintf(&envp[5], "REMOTEPORT=%s", port);
|
||||
xasprintf(&envp[6], "NAME=%s", myself->name);
|
||||
environment_add(&env, "REMOTEADDRESS=%s", address);
|
||||
environment_add(&env, "REMOTEPORT=%s", port);
|
||||
|
||||
execute_script(n->status.reachable ? "host-up" : "host-down", envp);
|
||||
execute_script(n->status.reachable ? "host-up" : "host-down", &env);
|
||||
|
||||
xasprintf(&name, n->status.reachable ? "hosts/%s-up" : "hosts/%s-down", n->name);
|
||||
execute_script(name, envp);
|
||||
execute_script(name, &env);
|
||||
|
||||
free(name);
|
||||
free(address);
|
||||
free(port);
|
||||
|
||||
for(int i = 0; i < 7; i++)
|
||||
free(envp[i]);
|
||||
environment_exit(&env);
|
||||
|
||||
subnet_update(n, NULL, n->status.reachable);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
ifconfig.c -- Generate platform specific interface configuration commands
|
||||
Copyright (C) 2016 Guus Sliepen <guus@tinc-vpn.org>
|
||||
Copyright (C) 2016-2017 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
|
||||
|
|
@ -104,13 +104,6 @@ void ifconfig_address(FILE *out, const char *value) {
|
|||
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;
|
||||
|
|
@ -118,6 +111,13 @@ void ifconfig_address(FILE *out, const char *value) {
|
|||
case SUBNET_IPV6: fprintf(out, "netsh inetface ipv6 set address \"$INTERFACE\" static %s\n", address_str); break;
|
||||
default: return;
|
||||
}
|
||||
#else // assume 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;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -152,8 +152,21 @@ void ifconfig_route(FILE *out, const char *value) {
|
|||
default: return;
|
||||
}
|
||||
}
|
||||
#elif defined(HAVE_BSD)
|
||||
// BSD route command is silly and doesn't accept an interface name as a destination.
|
||||
#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;
|
||||
}
|
||||
}
|
||||
#else // assume BSD
|
||||
if(!*gateway_str) {
|
||||
switch(subnet.type) {
|
||||
case SUBNET_IPV4:
|
||||
|
|
@ -180,19 +193,5 @@ void ifconfig_route(FILE *out, const char *value) {
|
|||
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
|
||||
}
|
||||
|
|
|
|||
12
src/info.c
12
src/info.c
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
info.c -- Show information about a node, subnet or address
|
||||
Copyright (C) 2012-2013 Guus Sliepen <guus@tinc-vpn.org>
|
||||
Copyright (C) 2012-2017 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
|
||||
|
|
@ -69,7 +69,7 @@ static int info_node(int fd, const char *item) {
|
|||
long int last_state_change;
|
||||
|
||||
while(recvline(fd, line, sizeof line)) {
|
||||
int n = sscanf(line, "%d %d %s %s %s port %s %d %d %d %d %x %"PRIx32" %s %s %d %hd %hd %hd %ld", &code, &req, node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_union.raw, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change);
|
||||
int n = sscanf(line, "%d %d %4095s %4095s %4095s port %4095s %d %d %d %d %x %"PRIx32" %4095s %4095s %d %hd %hd %hd %ld", &code, &req, node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_union.raw, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change);
|
||||
|
||||
if(n == 2)
|
||||
break;
|
||||
|
|
@ -91,7 +91,7 @@ static int info_node(int fd, const char *item) {
|
|||
}
|
||||
|
||||
while(recvline(fd, line, sizeof line)) {
|
||||
if(sscanf(line, "%d %d %s", &code, &req, node) == 2)
|
||||
if(sscanf(line, "%d %d %4095s", &code, &req, node) == 2)
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -158,7 +158,7 @@ static int info_node(int fd, const char *item) {
|
|||
printf("Edges: ");
|
||||
sendline(fd, "%d %d %s", CONTROL, REQ_DUMP_EDGES, item);
|
||||
while(recvline(fd, line, sizeof line)) {
|
||||
int n = sscanf(line, "%d %d %s %s", &code, &req, from, to);
|
||||
int n = sscanf(line, "%d %d %4095s %4095s", &code, &req, from, to);
|
||||
if(n == 2)
|
||||
break;
|
||||
if(n != 4) {
|
||||
|
|
@ -174,7 +174,7 @@ static int info_node(int fd, const char *item) {
|
|||
printf("Subnets: ");
|
||||
sendline(fd, "%d %d %s", CONTROL, REQ_DUMP_SUBNETS, item);
|
||||
while(recvline(fd, line, sizeof line)) {
|
||||
int n = sscanf(line, "%d %d %s %s", &code, &req, subnet, from);
|
||||
int n = sscanf(line, "%d %d %4095s %4095s", &code, &req, subnet, from);
|
||||
if(n == 2)
|
||||
break;
|
||||
if(n != 4) {
|
||||
|
|
@ -209,7 +209,7 @@ static int info_subnet(int fd, const char *item) {
|
|||
|
||||
sendline(fd, "%d %d %s", CONTROL, REQ_DUMP_SUBNETS, item);
|
||||
while(recvline(fd, line, sizeof line)) {
|
||||
int n = sscanf(line, "%d %d %s %s", &code, &req, netstr, owner);
|
||||
int n = sscanf(line, "%d %d %4095s %4095s", &code, &req, netstr, owner);
|
||||
if(n == 2)
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
invitation.c -- Create and accept invitations
|
||||
Copyright (C) 2013-2015 Guus Sliepen <guus@tinc-vpn.org>
|
||||
Copyright (C) 2013-2017 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
|
||||
|
|
@ -239,7 +239,7 @@ int cmd_invite(int argc, char *argv[]) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
char *myname = get_my_name(true);
|
||||
myname = get_my_name(true);
|
||||
if(!myname)
|
||||
return 1;
|
||||
|
||||
|
|
@ -252,14 +252,14 @@ int cmd_invite(int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
// If a daemon is running, ensure no other nodes know about this name
|
||||
bool found = false;
|
||||
if(connect_tincd(false)) {
|
||||
bool found = false;
|
||||
sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES);
|
||||
|
||||
while(recvline(fd, line, sizeof line)) {
|
||||
char node[4096];
|
||||
int code, req;
|
||||
if(sscanf(line, "%d %d %s", &code, &req, node) != 3)
|
||||
if(sscanf(line, "%d %d %4095s", &code, &req, node) != 3)
|
||||
break;
|
||||
if(!strcmp(node, argv[1]))
|
||||
found = true;
|
||||
|
|
@ -425,15 +425,13 @@ int cmd_invite(int argc, char *argv[]) {
|
|||
xasprintf(&url, "%s/%s%s", address, hash, cookie);
|
||||
|
||||
// Call the inviation-created script
|
||||
char *envp[6] = {};
|
||||
xasprintf(&envp[0], "NAME=%s", myname);
|
||||
xasprintf(&envp[1], "NETNAME=%s", netname);
|
||||
xasprintf(&envp[2], "NODE=%s", argv[1]);
|
||||
xasprintf(&envp[3], "INVITATION_FILE=%s", filename);
|
||||
xasprintf(&envp[4], "INVITATION_URL=%s", url);
|
||||
execute_script("invitation-created", envp);
|
||||
for(int i = 0; i < 6 && envp[i]; i++)
|
||||
free(envp[i]);
|
||||
environment_t env;
|
||||
environment_init(&env);
|
||||
environment_add(&env, "NODE=%s", argv[1]);
|
||||
environment_add(&env, "INVITATION_FILE=%s", filename);
|
||||
environment_add(&env, "INVITATION_URL=%s", url);
|
||||
execute_script("invitation-created", &env);
|
||||
environment_exit(&env);
|
||||
|
||||
puts(url);
|
||||
free(url);
|
||||
|
|
@ -609,6 +607,17 @@ make_names:
|
|||
return false;
|
||||
}
|
||||
|
||||
snprintf(filename, sizeof filename, "%s" SLASH "invitation-data", confbase);
|
||||
FILE *finv = fopen(filename, "w");
|
||||
if(!finv || fwrite(data, datalen, 1, finv) != 1) {
|
||||
fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno));
|
||||
fclose(fh);
|
||||
fclose(f);
|
||||
fclose(finv);
|
||||
return false;
|
||||
}
|
||||
fclose(finv);
|
||||
|
||||
snprintf(filename, sizeof filename, "%s" SLASH "tinc-up.invitation", confbase);
|
||||
FILE *fup = fopen(filename, "w");
|
||||
if(!fup) {
|
||||
|
|
@ -688,7 +697,7 @@ make_names:
|
|||
}
|
||||
|
||||
// Copy the safe variable to the right config file
|
||||
fprintf(variables[i].type & VAR_HOST ? fh : f, "%s = %s\n", l, value);
|
||||
fprintf((variables[i].type & VAR_HOST) ? fh : f, "%s = %s\n", l, value);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
|
@ -1046,7 +1055,7 @@ next:
|
|||
char hisname[4096] = "";
|
||||
int code, hismajor, hisminor = 0;
|
||||
|
||||
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) {
|
||||
if(!recvline(sock, line, sizeof line) || sscanf(line, "%d %4095s %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);
|
||||
goto next;
|
||||
|
|
|
|||
|
|
@ -139,6 +139,9 @@ static bool read_packet(vpn_packet_t *packet) {
|
|||
if(inlen <= 0) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s",
|
||||
device_info, device, strerror(errno));
|
||||
if (errno == EBADFD) { /* File descriptor in bad state */
|
||||
event_exit();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
logger.c -- logging code
|
||||
Copyright (C) 2004-2015 Guus Sliepen <guus@tinc-vpn.org>
|
||||
Copyright (C) 2004-2017 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2004-2005 Ivo Timmermans
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
|
@ -29,7 +29,7 @@
|
|||
#include "process.h"
|
||||
#include "sptps.h"
|
||||
|
||||
debug_t debug_level = DEBUG_NOTHING;
|
||||
int debug_level = DEBUG_NOTHING;
|
||||
static logmode_t logmode = LOGMODE_STDERR;
|
||||
static pid_t logpid;
|
||||
static FILE *logfile = NULL;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
logger.h -- header file for logger.c
|
||||
Copyright (C) 1998-2005 Ivo Timmermans
|
||||
2000-2012 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2017 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
|
||||
|
|
@ -67,7 +67,7 @@ enum {
|
|||
|
||||
#include <stdbool.h>
|
||||
|
||||
extern debug_t debug_level;
|
||||
extern int debug_level;
|
||||
extern bool logcontrol;
|
||||
extern int umbilical;
|
||||
extern void openlogger(const char *, logmode_t);
|
||||
|
|
|
|||
14
src/meta.c
14
src/meta.c
|
|
@ -65,6 +65,13 @@ bool send_meta(connection_t *c, const char *buffer, int length) {
|
|||
#ifdef DISABLE_LEGACY
|
||||
return false;
|
||||
#else
|
||||
if(length > c->outbudget) {
|
||||
logger(DEBUG_META, LOG_ERR, "Byte limit exceeded for encryption to %s (%s)", c->name, c->hostname);
|
||||
return false;
|
||||
} else {
|
||||
c->outbudget -= length;
|
||||
}
|
||||
|
||||
size_t outlen = length;
|
||||
|
||||
if(!cipher_encrypt(c->outcipher, buffer, length, buffer_prepare(&c->outbuf, length), &outlen, false) || outlen != length) {
|
||||
|
|
@ -220,6 +227,13 @@ bool receive_meta(connection_t *c) {
|
|||
#ifdef DISABLE_LEGACY
|
||||
return false;
|
||||
#else
|
||||
if(inlen > c->inbudget) {
|
||||
logger(DEBUG_META, LOG_ERR, "yte limit exceeded for decryption from %s (%s)", c->name, c->hostname);
|
||||
return false;
|
||||
} else {
|
||||
c->inbudget -= inlen;
|
||||
}
|
||||
|
||||
size_t outlen = inlen;
|
||||
|
||||
if(!cipher_decrypt(c->incipher, bufp, inlen, buffer_prepare(&c->inbuf, inlen), &outlen, false) || inlen != outlen) {
|
||||
|
|
|
|||
|
|
@ -214,6 +214,9 @@ static bool setup_device(void) {
|
|||
|
||||
logger(DEBUG_ALWAYS, LOG_INFO, "%s (%s) is a %s", device, iface, device_info);
|
||||
|
||||
device_read_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
device_write_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -226,9 +229,6 @@ static void enable_device(void) {
|
|||
|
||||
/* 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();
|
||||
}
|
||||
|
|
@ -237,6 +237,19 @@ static void disable_device(void) {
|
|||
logger(DEBUG_ALWAYS, LOG_INFO, "Disabling %s", device_info);
|
||||
|
||||
io_del(&device_read_io);
|
||||
|
||||
ULONG status = 0;
|
||||
DWORD len;
|
||||
DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof status, &status, sizeof status, &len, NULL);
|
||||
|
||||
/* Note that we don't try to cancel ongoing I/O here - we just stop listening.
|
||||
This is because some TAP-Win32 drivers don't seem to handle cancellation very well,
|
||||
especially when combined with other events such as the computer going to sleep - cases
|
||||
were observed where the GetOverlappedResult() would just block indefinitely and never
|
||||
return in that case. */
|
||||
}
|
||||
|
||||
static void close_device(void) {
|
||||
CancelIo(device_handle);
|
||||
|
||||
/* According to MSDN, CancelIo() does not necessarily wait for the operation to complete.
|
||||
|
|
@ -253,11 +266,6 @@ static void disable_device(void) {
|
|||
CloseHandle(device_read_overlapped.hEvent);
|
||||
CloseHandle(device_write_overlapped.hEvent);
|
||||
|
||||
ULONG status = 0;
|
||||
DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof status, &status, sizeof status, &len, NULL);
|
||||
}
|
||||
|
||||
static void close_device(void) {
|
||||
CloseHandle(device_handle); device_handle = INVALID_HANDLE_VALUE;
|
||||
|
||||
free(device); device = NULL;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
names.c -- generate commonly used (file)names
|
||||
Copyright (C) 1998-2005 Ivo Timmermans
|
||||
2000-2015 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2017 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
|
||||
|
|
@ -25,6 +25,7 @@
|
|||
#include "xalloc.h"
|
||||
|
||||
char *netname = NULL;
|
||||
char *myname = NULL;
|
||||
char *confdir = NULL; /* base configuration directory */
|
||||
char *confbase = NULL; /* base configuration directory for this instance of tinc */
|
||||
bool confbase_given;
|
||||
|
|
@ -137,6 +138,7 @@ void free_names(void) {
|
|||
free(logfilename);
|
||||
free(confbase);
|
||||
free(confdir);
|
||||
free(myname);
|
||||
|
||||
identname = NULL;
|
||||
netname = NULL;
|
||||
|
|
@ -145,4 +147,5 @@ void free_names(void) {
|
|||
logfilename = NULL;
|
||||
confbase = NULL;
|
||||
confdir = NULL;
|
||||
myname = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
names.h -- header for names.c
|
||||
Copyright (C) 1998-2005 Ivo Timmermans
|
||||
2000-2015 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2017 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
|
||||
|
|
@ -25,6 +25,7 @@ extern char *confdir;
|
|||
extern char *confbase;
|
||||
extern bool confbase_given;
|
||||
extern char *netname;
|
||||
extern char *myname;
|
||||
extern char *identname;
|
||||
extern char *unixsocketname;
|
||||
extern char *logfilename;
|
||||
|
|
|
|||
107
src/net.c
107
src/net.c
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
net.c -- most of the network code
|
||||
Copyright (C) 1998-2005 Ivo Timmermans,
|
||||
2000-2015 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2017 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2006 Scott Lamb <slamb@slamb.org>
|
||||
2011 Loïc Grenié <loic.grenie@gmail.com>
|
||||
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
#include "system.h"
|
||||
|
||||
#include "utils.h"
|
||||
#include "autoconnect.h"
|
||||
#include "conf.h"
|
||||
#include "connection.h"
|
||||
#include "device.h"
|
||||
|
|
@ -34,6 +34,7 @@
|
|||
#include "netutl.h"
|
||||
#include "protocol.h"
|
||||
#include "subnet.h"
|
||||
#include "utils.h"
|
||||
#include "xalloc.h"
|
||||
|
||||
int contradicting_add_edge = 0;
|
||||
|
|
@ -209,7 +210,7 @@ static void timeout_handler(void *data) {
|
|||
|
||||
// timeout during ping
|
||||
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));
|
||||
terminate_connection(c, c->edge);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -245,105 +246,9 @@ static void periodic_handler(void *data) {
|
|||
|
||||
/* If AutoConnect is set, check if we need to make or break connections. */
|
||||
|
||||
if(autoconnect && node_tree->count > 1) {
|
||||
/* Count number of active connections */
|
||||
int nc = 0;
|
||||
for list_each(connection_t, c, connection_list) {
|
||||
if(c->edge)
|
||||
nc++;
|
||||
}
|
||||
if(autoconnect && node_tree->count > 1)
|
||||
do_autoconnect();
|
||||
|
||||
if(nc < 3) {
|
||||
/* Not enough active connections, try to add one.
|
||||
Choose a random node, if we don't have a connection to it,
|
||||
and we are not already trying to make one, create an
|
||||
outgoing connection to this node.
|
||||
*/
|
||||
int count = 0;
|
||||
for splay_each(node_t, n, node_tree) {
|
||||
if(n == myself || n->connection || !(n->status.has_address || n->status.reachable))
|
||||
continue;
|
||||
count++;
|
||||
}
|
||||
|
||||
if(!count)
|
||||
goto end;
|
||||
|
||||
int r = rand() % count;
|
||||
|
||||
for splay_each(node_t, n, node_tree) {
|
||||
if(n == myself || n->connection || !(n->status.has_address || n->status.reachable))
|
||||
continue;
|
||||
|
||||
if(r--)
|
||||
continue;
|
||||
|
||||
bool found = false;
|
||||
|
||||
for list_each(outgoing_t, outgoing, outgoing_list) {
|
||||
if(!strcmp(outgoing->name, n->name)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!found) {
|
||||
logger(DEBUG_CONNECTIONS, LOG_INFO, "Autoconnecting to %s", n->name);
|
||||
outgoing_t *outgoing = xzalloc(sizeof *outgoing);
|
||||
outgoing->name = xstrdup(n->name);
|
||||
list_insert_tail(outgoing_list, outgoing);
|
||||
setup_outgoing_connection(outgoing);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
} else if(nc > 3) {
|
||||
/* Too many active connections, try to remove one.
|
||||
Choose a random outgoing connection to a node
|
||||
that has at least one other connection.
|
||||
*/
|
||||
int r = rand() % nc;
|
||||
int i = 0;
|
||||
|
||||
for list_each(connection_t, c, connection_list) {
|
||||
if(!c->edge)
|
||||
continue;
|
||||
|
||||
if(i++ != r)
|
||||
continue;
|
||||
|
||||
if(!c->outgoing || !c->node || c->node->edge_tree->count < 2)
|
||||
break;
|
||||
|
||||
logger(DEBUG_CONNECTIONS, LOG_INFO, "Autodisconnecting from %s", c->name);
|
||||
list_delete(outgoing_list, c->outgoing);
|
||||
c->outgoing = NULL;
|
||||
terminate_connection(c, c->edge);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(nc >= 3) {
|
||||
/* If we have enough active connections,
|
||||
remove any pending outgoing connections.
|
||||
*/
|
||||
for list_each(outgoing_t, o, outgoing_list) {
|
||||
bool found = false;
|
||||
for list_each(connection_t, c, connection_list) {
|
||||
if(c->outgoing == o) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
logger(DEBUG_CONNECTIONS, LOG_INFO, "Cancelled outgoing connection to %s", o->name);
|
||||
list_delete_node(outgoing_list, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
timeout_set(data, &(struct timeval){5, rand() % 100000});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -126,8 +126,9 @@ typedef struct outgoing_t {
|
|||
int timeout;
|
||||
splay_tree_t *config_tree;
|
||||
struct config_t *cfg;
|
||||
struct addrinfo *ai;
|
||||
struct addrinfo *ai; // addresses from config files
|
||||
struct addrinfo *aip;
|
||||
struct addrinfo *kai; // addresses known via other online nodes (use free_known_addresses())
|
||||
timeout_t ev;
|
||||
} outgoing_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
net_packet.c -- Handles in- and outgoing VPN packets
|
||||
Copyright (C) 1998-2005 Ivo Timmermans,
|
||||
2000-2016 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2017 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2010 Timothy Redaelli <timothy@redaelli.eu>
|
||||
2010 Brandon Black <blblack@gmail.com>
|
||||
|
||||
|
|
@ -846,6 +846,7 @@ bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t
|
|||
|
||||
vpn_packet_t inpkt;
|
||||
inpkt.offset = DEFAULT_PACKET_OFFSET;
|
||||
inpkt.priority = 0;
|
||||
|
||||
if(type == PKT_PROBE) {
|
||||
if(!from->status.udppacket) {
|
||||
|
|
@ -1573,10 +1574,19 @@ void handle_device_data(void *data, int flags) {
|
|||
vpn_packet_t packet;
|
||||
packet.offset = DEFAULT_PACKET_OFFSET;
|
||||
packet.priority = 0;
|
||||
static int errors = 0;
|
||||
|
||||
if(devops.read(&packet)) {
|
||||
errors = 0;
|
||||
myself->in_packets++;
|
||||
myself->in_bytes += packet.len;
|
||||
route(myself, &packet);
|
||||
} else {
|
||||
usleep(errors * 50000);
|
||||
errors++;
|
||||
if(errors > 10) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Too many errors from %s, exiting!", device);
|
||||
event_exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
net_setup.c -- Setup.
|
||||
Copyright (C) 1998-2005 Ivo Timmermans,
|
||||
2000-2016 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2017 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2006 Scott Lamb <slamb@slamb.org>
|
||||
2010 Brandon Black <blblack@gmail.com>
|
||||
|
||||
|
|
@ -48,7 +48,6 @@
|
|||
#endif
|
||||
|
||||
char *myport;
|
||||
static char *myname;
|
||||
static io_t device_io;
|
||||
devops_t devops;
|
||||
bool device_standby = false;
|
||||
|
|
@ -612,6 +611,9 @@ bool setup_myself_reloadable(void) {
|
|||
|
||||
get_config_bool(lookup_config(config_tree, "DisableBuggyPeers"), &disablebuggypeers);
|
||||
|
||||
if(!get_config_int(lookup_config(config_tree, "InvitationExpire"), &invitation_lifetime))
|
||||
invitation_lifetime = 604800; // 1 week
|
||||
|
||||
read_invitation_key();
|
||||
|
||||
return true;
|
||||
|
|
@ -705,29 +707,17 @@ void device_enable(void) {
|
|||
|
||||
/* Run tinc-up script to further initialize the tap interface */
|
||||
|
||||
char *envp[5] = {NULL};
|
||||
xasprintf(&envp[0], "NETNAME=%s", netname ? : "");
|
||||
xasprintf(&envp[1], "DEVICE=%s", device ? : "");
|
||||
xasprintf(&envp[2], "INTERFACE=%s", iface ? : "");
|
||||
xasprintf(&envp[3], "NAME=%s", myname);
|
||||
|
||||
execute_script("tinc-up", envp);
|
||||
|
||||
for(int i = 0; i < 4; i++)
|
||||
free(envp[i]);
|
||||
environment_t env;
|
||||
environment_init(&env);
|
||||
execute_script("tinc-up", &env);
|
||||
environment_exit(&env);
|
||||
}
|
||||
|
||||
void device_disable(void) {
|
||||
char *envp[5] = {NULL};
|
||||
xasprintf(&envp[0], "NETNAME=%s", netname ? : "");
|
||||
xasprintf(&envp[1], "DEVICE=%s", device ? : "");
|
||||
xasprintf(&envp[2], "INTERFACE=%s", iface ? : "");
|
||||
xasprintf(&envp[3], "NAME=%s", myname);
|
||||
|
||||
execute_script("tinc-down", envp);
|
||||
|
||||
for(int i = 0; i < 4; i++)
|
||||
free(envp[i]);
|
||||
environment_t env;
|
||||
environment_init(&env);
|
||||
execute_script("tinc-down", &env);
|
||||
environment_exit(&env);
|
||||
|
||||
if (devops.disable)
|
||||
devops.disable();
|
||||
|
|
@ -857,7 +847,7 @@ static bool setup_myself(void) {
|
|||
/* Generate packet encryption key */
|
||||
|
||||
if(!get_config_string(lookup_config(config_tree, "Cipher"), &cipher))
|
||||
cipher = xstrdup("blowfish");
|
||||
cipher = xstrdup("aes-256-cbc");
|
||||
|
||||
if(!strcasecmp(cipher, "none")) {
|
||||
myself->incipher = NULL;
|
||||
|
|
@ -881,7 +871,7 @@ static bool setup_myself(void) {
|
|||
}
|
||||
|
||||
if(!get_config_string(lookup_config(config_tree, "Digest"), &digest))
|
||||
digest = xstrdup("sha1");
|
||||
digest = xstrdup("sha256");
|
||||
|
||||
if(!strcasecmp(digest, "none")) {
|
||||
myself->indigest = NULL;
|
||||
|
|
@ -929,6 +919,8 @@ static bool setup_myself(void) {
|
|||
devops = raw_socket_devops;
|
||||
else if(!strcasecmp(type, "multicast"))
|
||||
devops = multicast_devops;
|
||||
else if(!strcasecmp(type, "fd"))
|
||||
devops = fd_devops;
|
||||
#ifdef ENABLE_UML
|
||||
else if(!strcasecmp(type, "uml"))
|
||||
devops = uml_devops;
|
||||
|
|
@ -1148,7 +1140,6 @@ void close_network_connections(void) {
|
|||
|
||||
exit_control();
|
||||
|
||||
free(myname);
|
||||
free(scriptextension);
|
||||
free(scriptinterpreter);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
net_socket.c -- Handle various kinds of sockets.
|
||||
Copyright (C) 1998-2005 Ivo Timmermans,
|
||||
2000-2016 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2017 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2006 Scott Lamb <slamb@slamb.org>
|
||||
2009 Florian Forster <octo@verplant.org>
|
||||
|
||||
|
|
@ -382,7 +382,7 @@ static void handle_meta_write(connection_t *c) {
|
|||
if(!sockerrno || sockerrno == EPIPE) {
|
||||
logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection closed by %s (%s)", c->name, c->hostname);
|
||||
} else if(sockwouldblock(sockerrno)) {
|
||||
logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Sending %d bytes to %s (%s) would block", c->outbuf.len - c->outbuf.offset, c->name, c->hostname);
|
||||
logger(DEBUG_META, LOG_DEBUG, "Sending %d bytes to %s (%s) would block", c->outbuf.len - c->outbuf.offset, c->name, c->hostname);
|
||||
return;
|
||||
} else {
|
||||
logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not send %d bytes of data to %s (%s): %s", c->outbuf.len - c->outbuf.offset, c->name, c->hostname, sockstrerror(sockerrno));
|
||||
|
|
@ -441,13 +441,20 @@ static void handle_meta_io(void *data, int flags) {
|
|||
handle_meta_connection_data(c);
|
||||
}
|
||||
|
||||
static void free_known_addresses(struct addrinfo *ai) {
|
||||
for(struct addrinfo *aip = ai, *next; aip; aip = next) {
|
||||
next = aip->ai_next;
|
||||
free(aip);
|
||||
}
|
||||
}
|
||||
|
||||
bool do_outgoing_connection(outgoing_t *outgoing) {
|
||||
char *address, *port, *space;
|
||||
struct addrinfo *proxyai = NULL;
|
||||
int result;
|
||||
|
||||
begin:
|
||||
if(!outgoing->ai) {
|
||||
if(!outgoing->ai && !outgoing->kai) {
|
||||
if(!outgoing->cfg) {
|
||||
logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not set up a meta connection to %s", outgoing->name);
|
||||
retry_outgoing(outgoing);
|
||||
|
|
@ -477,6 +484,11 @@ begin:
|
|||
if(outgoing->ai)
|
||||
freeaddrinfo(outgoing->ai);
|
||||
outgoing->ai = NULL;
|
||||
|
||||
if(outgoing->kai)
|
||||
free_known_addresses(outgoing->kai);
|
||||
outgoing->kai = NULL;
|
||||
|
||||
goto begin;
|
||||
}
|
||||
|
||||
|
|
@ -570,6 +582,7 @@ begin:
|
|||
// Find edges pointing to this node, and use them to build a list of unique, known addresses.
|
||||
static struct addrinfo *get_known_addresses(node_t *n) {
|
||||
struct addrinfo *ai = NULL;
|
||||
struct addrinfo *oai = NULL;
|
||||
|
||||
for splay_each(edge_t, e, n->edge_tree) {
|
||||
if(!e->reverse)
|
||||
|
|
@ -585,16 +598,15 @@ static struct addrinfo *get_known_addresses(node_t *n) {
|
|||
if(found)
|
||||
continue;
|
||||
|
||||
struct addrinfo *nai = xzalloc(sizeof *nai);
|
||||
if(ai)
|
||||
ai->ai_next = nai;
|
||||
ai = nai;
|
||||
oai = ai;
|
||||
ai = xzalloc(sizeof *ai);
|
||||
ai->ai_family = e->reverse->address.sa.sa_family;
|
||||
ai->ai_socktype = SOCK_STREAM;
|
||||
ai->ai_protocol = IPPROTO_TCP;
|
||||
ai->ai_addrlen = SALEN(e->reverse->address.sa);
|
||||
ai->ai_addr = xmalloc(ai->ai_addrlen);
|
||||
memcpy(ai->ai_addr, &e->reverse->address, ai->ai_addrlen);
|
||||
ai->ai_next = oai;
|
||||
}
|
||||
|
||||
return ai;
|
||||
|
|
@ -621,8 +633,8 @@ void setup_outgoing_connection(outgoing_t *outgoing) {
|
|||
|
||||
if(!outgoing->cfg) {
|
||||
if(n)
|
||||
outgoing->aip = outgoing->ai = get_known_addresses(n);
|
||||
if(!outgoing->ai) {
|
||||
outgoing->aip = outgoing->kai = get_known_addresses(n);
|
||||
if(!outgoing->kai) {
|
||||
logger(DEBUG_ALWAYS, LOG_DEBUG, "No address known for %s", outgoing->name);
|
||||
goto remove;
|
||||
}
|
||||
|
|
@ -777,6 +789,9 @@ static void free_outgoing(outgoing_t *outgoing) {
|
|||
if(outgoing->ai)
|
||||
freeaddrinfo(outgoing->ai);
|
||||
|
||||
if(outgoing->kai)
|
||||
free_known_addresses(outgoing->kai);
|
||||
|
||||
if(outgoing->config_tree)
|
||||
exit_configuration(&outgoing->config_tree);
|
||||
|
||||
|
|
|
|||
|
|
@ -186,9 +186,9 @@ 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)
|
||||
snprintf(id + 2 * c, 3, "%02hhx", n->id.x[c]);
|
||||
snprintf(id + 2 * c, 3, "%02x", 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,
|
||||
send_request(c, "%d %d %s %s %s %d %d %d %d %x %x %s %s %d %d %d %d %ld", CONTROL, REQ_DUMP_NODES,
|
||||
n->name, id, n->hostname ?: "unknown port unknown",
|
||||
#ifdef DISABLE_LEGACY
|
||||
0, 0, 0,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
cipher.c -- Symmetric block cipher handling
|
||||
Copyright (C) 2007-2013 Guus Sliepen <guus@tinc-vpn.org>
|
||||
Copyright (C) 2007-2017 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
|
||||
|
|
@ -62,10 +62,6 @@ cipher_t *cipher_open_by_nid(int nid) {
|
|||
return cipher_open(evp_cipher);
|
||||
}
|
||||
|
||||
cipher_t *cipher_open_blowfish_ofb(void) {
|
||||
return cipher_open(EVP_bf_ofb());
|
||||
}
|
||||
|
||||
void cipher_close(cipher_t *cipher) {
|
||||
if(!cipher)
|
||||
return;
|
||||
|
|
@ -81,6 +77,24 @@ size_t cipher_keylength(const cipher_t *cipher) {
|
|||
return EVP_CIPHER_key_length(cipher->cipher) + EVP_CIPHER_iv_length(cipher->cipher);
|
||||
}
|
||||
|
||||
uint64_t cipher_budget(const cipher_t *cipher) {
|
||||
/* Hopefully some failsafe way to calculate the maximum amount of bytes to
|
||||
send/receive with a given cipher before we might run into birthday paradox
|
||||
attacks. Because we might use different modes, the block size of the mode
|
||||
might be 1 byte. In that case, use the IV length. Ensure the whole thing
|
||||
is limited to what can be represented with a 64 bits integer.
|
||||
*/
|
||||
|
||||
if(!cipher || !cipher->cipher)
|
||||
return UINT64_MAX; // NULL cipher
|
||||
|
||||
int ivlen = EVP_CIPHER_iv_length(cipher->cipher);
|
||||
int blklen = EVP_CIPHER_block_size(cipher->cipher);
|
||||
int len = blklen > 1 ? blklen : ivlen > 1 ? ivlen : 8;
|
||||
int bits = len * 4 - 1;
|
||||
return bits < 64 ? UINT64_C(1) << bits : UINT64_MAX;
|
||||
}
|
||||
|
||||
size_t cipher_blocksize(const cipher_t *cipher) {
|
||||
if(!cipher || !cipher->cipher)
|
||||
return 1;
|
||||
|
|
@ -123,7 +137,7 @@ bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou
|
|||
int len, pad;
|
||||
if(EVP_EncryptInit_ex(cipher->ctx, NULL, NULL, NULL, NULL)
|
||||
&& EVP_EncryptUpdate(cipher->ctx, (unsigned char *)outdata, &len, indata, inlen)
|
||||
&& EVP_EncryptFinal(cipher->ctx, (unsigned char *)outdata + len, &pad)) {
|
||||
&& EVP_EncryptFinal_ex(cipher->ctx, (unsigned char *)outdata + len, &pad)) {
|
||||
if(outlen) *outlen = len + pad;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -144,7 +158,7 @@ bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou
|
|||
int len, pad;
|
||||
if(EVP_DecryptInit_ex(cipher->ctx, NULL, NULL, NULL, NULL)
|
||||
&& EVP_DecryptUpdate(cipher->ctx, (unsigned char *)outdata, &len, indata, inlen)
|
||||
&& EVP_DecryptFinal(cipher->ctx, (unsigned char *)outdata + len, &pad)) {
|
||||
&& EVP_DecryptFinal_ex(cipher->ctx, (unsigned char *)outdata + len, &pad)) {
|
||||
if(outlen) *outlen = len + pad;
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
digest.c -- Digest handling
|
||||
Copyright (C) 2007-2013 Guus Sliepen <guus@tinc-vpn.org>
|
||||
Copyright (C) 2007-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
|
||||
|
|
@ -64,10 +64,6 @@ digest_t *digest_open_by_nid(int nid, int maclength) {
|
|||
return digest_open(evp_md, maclength);
|
||||
}
|
||||
|
||||
digest_t *digest_open_sha1(int maclength) {
|
||||
return digest_open(EVP_sha1(), maclength);
|
||||
}
|
||||
|
||||
bool digest_set_key(digest_t *digest, const void *key, size_t len) {
|
||||
digest->key = xrealloc(digest->key, len);
|
||||
memcpy(digest->key, key, len);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
protocol.h -- header for protocol.c
|
||||
Copyright (C) 1999-2005 Ivo Timmermans,
|
||||
2000-2013 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2017 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
|
||||
|
|
@ -62,6 +62,7 @@ extern bool tunnelserver;
|
|||
extern bool strictsubnets;
|
||||
extern bool experimental;
|
||||
|
||||
extern int invitation_lifetime;
|
||||
extern ecdsa_t *invitation_key;
|
||||
|
||||
/* Maximum size of strings in a request.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
protocol_auth.c -- handle the meta-protocol, authentication
|
||||
Copyright (C) 1999-2005 Ivo Timmermans,
|
||||
2000-2014 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2017 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
|
||||
|
|
@ -47,6 +47,7 @@
|
|||
|
||||
#include "ed25519/sha512.h"
|
||||
|
||||
int invitation_lifetime;
|
||||
ecdsa_t *invitation_key = NULL;
|
||||
|
||||
static bool send_proxyrequest(connection_t *c) {
|
||||
|
|
@ -180,21 +181,18 @@ static bool finalize_invitation(connection_t *c, const char *data, uint16_t len)
|
|||
logger(DEBUG_CONNECTIONS, LOG_INFO, "Key succesfully received from %s (%s)", c->name, c->hostname);
|
||||
|
||||
// Call invitation-accepted script
|
||||
char *envp[7] = {NULL};
|
||||
environment_t env;
|
||||
char *address, *port;
|
||||
|
||||
xasprintf(&envp[0], "NETNAME=%s", netname ? : "");
|
||||
xasprintf(&envp[1], "DEVICE=%s", device ? : "");
|
||||
xasprintf(&envp[2], "INTERFACE=%s", iface ? : "");
|
||||
xasprintf(&envp[3], "NODE=%s", c->name);
|
||||
environment_init(&env);
|
||||
environment_add(&env, "NODE=%s", c->name);
|
||||
sockaddr2str(&c->address, &address, &port);
|
||||
xasprintf(&envp[4], "REMOTEADDRESS=%s", address);
|
||||
xasprintf(&envp[5], "NAME=%s", myself->name);
|
||||
environment_add(&env, "REMOTEADDRESS=%s", address);
|
||||
environment_add(&env, "NAME=%s", myself->name);
|
||||
|
||||
execute_script("invitation-accepted", envp);
|
||||
execute_script("invitation-accepted", &env);
|
||||
|
||||
for(int i = 0; envp[i] && i < 7; i++)
|
||||
free(envp[i]);
|
||||
environment_exit(&env);
|
||||
|
||||
sptps_send_record(&c->sptps, 2, data, 0);
|
||||
return true;
|
||||
|
|
@ -235,6 +233,18 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const void *dat
|
|||
return false;
|
||||
}
|
||||
|
||||
// Check the timestamp of the invitation
|
||||
struct stat st;
|
||||
if(stat(usedname, &st)) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Could not stat %s", usedname);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(st.st_mtime + invitation_lifetime < now.tv_sec) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s tried to use expired invitation %s", c->hostname, cookie);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Open the renamed file
|
||||
FILE *f = fopen(usedname, "r");
|
||||
if(!f) {
|
||||
|
|
@ -284,7 +294,7 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const void *dat
|
|||
bool id_h(connection_t *c, const char *request) {
|
||||
char name[MAX_STRING_SIZE];
|
||||
|
||||
if(sscanf(request, "%*d " MAX_STRING " %d.%d", name, &c->protocol_major, &c->protocol_minor) < 2) {
|
||||
if(sscanf(request, "%*d " MAX_STRING " %2d.%3d", name, &c->protocol_major, &c->protocol_minor) < 2) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ID", c->name,
|
||||
c->hostname);
|
||||
return false;
|
||||
|
|
@ -421,10 +431,24 @@ bool send_metakey(connection_t *c) {
|
|||
if(!read_rsa_public_key(c))
|
||||
return false;
|
||||
|
||||
if(!(c->outcipher = cipher_open_blowfish_ofb()))
|
||||
/* We need to use a stream mode for the meta protocol. Use AES for this,
|
||||
but try to match the key size with the one from the cipher selected
|
||||
by Cipher.
|
||||
*/
|
||||
|
||||
int keylen = cipher_keylength(myself->incipher);
|
||||
if(keylen <= 16)
|
||||
c->outcipher = cipher_open_by_name("aes-128-cfb");
|
||||
else if(keylen <= 24)
|
||||
c->outcipher = cipher_open_by_name("aes-192-cfb");
|
||||
else
|
||||
c->outcipher = cipher_open_by_name("aes-256-cfb");
|
||||
if(!c)
|
||||
return false;
|
||||
|
||||
if(!(c->outdigest = digest_open_sha1(-1)))
|
||||
c->outbudget = cipher_budget(c->outcipher);
|
||||
|
||||
if(!(c->outdigest = digest_open_by_name("sha256", -1)))
|
||||
return false;
|
||||
|
||||
const size_t len = rsa_size(c->rsa);
|
||||
|
|
@ -536,6 +560,8 @@ bool metakey_h(connection_t *c, const char *request) {
|
|||
c->incipher = NULL;
|
||||
}
|
||||
|
||||
c->inbudget = cipher_budget(c->incipher);
|
||||
|
||||
if(digest) {
|
||||
if(!(c->indigest = digest_open_by_nid(digest, -1))) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error during initialisation of digest from %s (%s)", c->name, c->hostname);
|
||||
|
|
@ -872,8 +898,10 @@ bool ack_h(connection_t *c, const char *request) {
|
|||
socklen_t local_salen = sizeof local_sa;
|
||||
if (getsockname(c->socket, &local_sa.sa, &local_salen) < 0)
|
||||
logger(DEBUG_ALWAYS, LOG_WARNING, "Could not get local socket address for connection with %s", c->name);
|
||||
else
|
||||
else {
|
||||
sockaddr_setport(&local_sa, myport);
|
||||
c->edge->local_address = local_sa;
|
||||
}
|
||||
c->edge->weight = (weight + c->estimated_weight) / 2;
|
||||
c->edge->connection = c;
|
||||
c->edge->options = c->options;
|
||||
|
|
|
|||
|
|
@ -132,63 +132,52 @@ 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)) {
|
||||
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);
|
||||
e->options = options;
|
||||
if(sockaddrcmp(&e->address, &address)) {
|
||||
sockaddrfree(&e->address);
|
||||
e->address = address;
|
||||
}
|
||||
if(e->weight != weight) {
|
||||
splay_node_t *node = splay_unlink(edge_weight_tree, e);
|
||||
e->weight = weight;
|
||||
splay_insert_node(edge_weight_tree, node);
|
||||
}
|
||||
bool new_address = sockaddrcmp(&e->address, &address);
|
||||
// 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
|
||||
bool new_local_address = local_address.sa.sa_family && local_address.sa.sa_family != AF_UNKNOWN &&
|
||||
sockaddrcmp(&e->local_address, &local_address);
|
||||
|
||||
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 {
|
||||
if(e->weight == weight && e->options == options && !new_address && !new_local_address) {
|
||||
sockaddrfree(&address);
|
||||
sockaddrfree(&local_address);
|
||||
return true;
|
||||
}
|
||||
|
||||
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(&address);
|
||||
sockaddrfree(&local_address);
|
||||
return true;
|
||||
}
|
||||
|
||||
logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) which does not match existing entry",
|
||||
"ADD_EDGE", c->name, c->hostname);
|
||||
|
||||
e->options = options;
|
||||
|
||||
if(new_address) {
|
||||
sockaddrfree(&e->address);
|
||||
e->address = address;
|
||||
} else {
|
||||
sockaddrfree(&address);
|
||||
}
|
||||
|
||||
if(new_local_address) {
|
||||
sockaddrfree(&e->local_address);
|
||||
e->local_address = local_address;
|
||||
} else {
|
||||
sockaddrfree(&local_address);
|
||||
}
|
||||
|
||||
if(e->weight != weight) {
|
||||
splay_node_t *node = splay_unlink(edge_weight_tree, e);
|
||||
e->weight = weight;
|
||||
splay_insert_node(edge_weight_tree, node);
|
||||
}
|
||||
} 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);
|
||||
|
|
@ -198,20 +187,20 @@ bool add_edge_h(connection_t *c, const char *request) {
|
|||
e->to = to;
|
||||
send_del_edge(c, e);
|
||||
free_edge(e);
|
||||
sockaddrfree(&address);
|
||||
sockaddrfree(&local_address);
|
||||
return true;
|
||||
} else {
|
||||
e = new_edge();
|
||||
e->from = from;
|
||||
e->to = to;
|
||||
e->address = address;
|
||||
e->local_address = local_address;
|
||||
e->options = options;
|
||||
e->weight = weight;
|
||||
edge_add(e);
|
||||
}
|
||||
|
||||
e = new_edge();
|
||||
e->from = from;
|
||||
e->to = to;
|
||||
e->address = address;
|
||||
e->local_address = local_address;
|
||||
e->options = options;
|
||||
e->weight = weight;
|
||||
edge_add(e);
|
||||
|
||||
done:
|
||||
/* Tell the rest about the new edge */
|
||||
|
||||
if(!tunnelserver)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
protocol_key.c -- handle the meta-protocol, key exchange
|
||||
Copyright (C) 1999-2005 Ivo Timmermans,
|
||||
2000-2014 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2017 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
|
||||
|
|
@ -356,7 +356,7 @@ bool ans_key_h(connection_t *c, const char *request) {
|
|||
char key[MAX_STRING_SIZE];
|
||||
char address[MAX_STRING_SIZE] = "";
|
||||
char port[MAX_STRING_SIZE] = "";
|
||||
int cipher, digest, maclength, compression, keylen;
|
||||
int cipher, digest, maclength, compression;
|
||||
node_t *from, *to;
|
||||
|
||||
if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %d %d "MAX_STRING" "MAX_STRING,
|
||||
|
|
@ -489,7 +489,7 @@ bool ans_key_h(connection_t *c, const char *request) {
|
|||
|
||||
/* Process key */
|
||||
|
||||
keylen = hex2bin(key, key, sizeof key);
|
||||
int keylen = hex2bin(key, key, sizeof key);
|
||||
|
||||
if(keylen != (from->outcipher ? cipher_keylength(from->outcipher) : 1)) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname);
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ bool send_tcppacket(connection_t *c, const vpn_packet_t *packet) {
|
|||
if(2.0 * c->outbuf.len / (float)maxoutbufsize - 1 > (float)rand()/(float)RAND_MAX)
|
||||
return true;
|
||||
|
||||
if(!send_request(c, "%d %hd", PACKET, packet->len))
|
||||
if(!send_request(c, "%d %d", PACKET, packet->len))
|
||||
return false;
|
||||
|
||||
return send_meta(c, (char *)DATA(packet), packet->len);
|
||||
|
|
@ -194,6 +194,11 @@ bool send_udp_info(node_t *from, node_t *to) {
|
|||
farther than the static relay. */
|
||||
to = (to->via == myself) ? to->nexthop : to->via;
|
||||
|
||||
if (to == NULL) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Something went wrong when selecting relay - possible fake UDP_INFO");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Skip cases where sending UDP info messages doesn't make sense.
|
||||
This is done here in order to avoid repeating the same logic in multiple callsites. */
|
||||
|
||||
|
|
|
|||
15
src/route.c
15
src/route.c
|
|
@ -510,7 +510,7 @@ static void route_broadcast(node_t *source, vpn_packet_t *packet) {
|
|||
static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t ether_size) {
|
||||
struct ip ip;
|
||||
vpn_packet_t fragment;
|
||||
int len, maxlen, todo;
|
||||
int maxlen, todo;
|
||||
uint8_t *offset;
|
||||
uint16_t ip_off, origf;
|
||||
|
||||
|
|
@ -537,7 +537,7 @@ static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t et
|
|||
ip_off &= IP_OFFMASK;
|
||||
|
||||
while(todo) {
|
||||
len = todo > maxlen ? maxlen : todo;
|
||||
int len = todo > maxlen ? maxlen : todo;
|
||||
memcpy(DATA(&fragment) + ether_size + ip_size, offset, len);
|
||||
todo -= len;
|
||||
offset += len;
|
||||
|
|
@ -683,6 +683,9 @@ static void route_ipv6(node_t *source, vpn_packet_t *packet) {
|
|||
if(!do_decrement_ttl(source, packet))
|
||||
return;
|
||||
|
||||
if(priorityinheritance)
|
||||
packet->priority = ((DATA(packet)[14] & 0x0f) << 4) | (DATA(packet)[15] >> 4);
|
||||
|
||||
via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via;
|
||||
|
||||
if(via == source) {
|
||||
|
|
@ -954,8 +957,12 @@ static void route_mac(node_t *source, vpn_packet_t *packet) {
|
|||
|
||||
uint16_t type = DATA(packet)[12] << 8 | DATA(packet)[13];
|
||||
|
||||
if(priorityinheritance && type == ETH_P_IP && packet->len >= ether_size + ip_size)
|
||||
packet->priority = DATA(packet)[15];
|
||||
if(priorityinheritance) {
|
||||
if(type == ETH_P_IP && packet->len >= ether_size + ip_size)
|
||||
packet->priority = DATA(packet)[15];
|
||||
else if(type == ETH_P_IPV6 && packet->len >= ether_size + ip6_size)
|
||||
packet->priority = ((DATA(packet)[14] & 0x0f) << 4) | (DATA(packet)[15] >> 4);
|
||||
}
|
||||
|
||||
// Handle packets larger than PMTU
|
||||
|
||||
|
|
|
|||
64
src/script.c
64
src/script.c
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
script.c -- call an external script
|
||||
Copyright (C) 1999-2005 Ivo Timmermans,
|
||||
2000-2015 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2017 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 "conf.h"
|
||||
#include "device.h"
|
||||
#include "logger.h"
|
||||
#include "names.h"
|
||||
#include "script.h"
|
||||
|
|
@ -63,7 +64,58 @@ static void putenv(const char *p) {}
|
|||
static void unputenv(const char *p) {}
|
||||
#endif
|
||||
|
||||
bool execute_script(const char *name, char **envp) {
|
||||
static const int min_env_size = 10;
|
||||
|
||||
int environment_add(environment_t *env, const char *format, ...) {
|
||||
if(env->n >= env->size) {
|
||||
env->size = env->n ? env->n * 2 : min_env_size;
|
||||
env->entries = xrealloc(env->entries, env->size * sizeof *env->entries);
|
||||
}
|
||||
|
||||
if(format) {
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
vasprintf(&env->entries[env->n], format, ap);
|
||||
va_end(ap);
|
||||
} else {
|
||||
env->entries[env->n] = NULL;
|
||||
}
|
||||
|
||||
return env->n++;
|
||||
}
|
||||
|
||||
void environment_update(environment_t *env, int pos, const char *format, ...) {
|
||||
free(env->entries[pos]);
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
vasprintf(&env->entries[pos], format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void environment_init(environment_t *env) {
|
||||
env->n = 0;
|
||||
env->size = min_env_size;
|
||||
env->entries = xzalloc(env->size * sizeof *env->entries);
|
||||
|
||||
if(netname)
|
||||
environment_add(env, "NETNAME=%s", netname);
|
||||
if(myname)
|
||||
environment_add(env, "NAME=%s", myname);
|
||||
if(device)
|
||||
environment_add(env, "DEVICE=%s", device);
|
||||
if(iface)
|
||||
environment_add(env, "INTERFACE=%s", iface);
|
||||
if(debug_level >= 0)
|
||||
environment_add(env, "DEBUG=%d", debug_level);
|
||||
}
|
||||
|
||||
void environment_exit(environment_t *env) {
|
||||
for(int i = 0; i < env->n; i++)
|
||||
free(env->entries[i]);
|
||||
free(env->entries);
|
||||
}
|
||||
|
||||
bool execute_script(const char *name, environment_t *env) {
|
||||
char scriptname[PATH_MAX];
|
||||
char *command;
|
||||
|
||||
|
|
@ -107,8 +159,8 @@ bool execute_script(const char *name, char **envp) {
|
|||
|
||||
/* Set environment */
|
||||
|
||||
for(int i = 0; envp[i]; i++)
|
||||
putenv(envp[i]);
|
||||
for(int i = 0; i < env->n; i++)
|
||||
putenv(env->entries[i]);
|
||||
|
||||
if(scriptinterpreter)
|
||||
xasprintf(&command, "%s \"%s\"", scriptinterpreter, scriptname);
|
||||
|
|
@ -121,8 +173,8 @@ bool execute_script(const char *name, char **envp) {
|
|||
|
||||
/* Unset environment */
|
||||
|
||||
for(int i = 0; envp[i]; i++)
|
||||
unputenv(envp[i]);
|
||||
for(int i = 0; i < env->n; i++)
|
||||
unputenv(env->entries[i]);
|
||||
|
||||
if(status != -1) {
|
||||
#ifdef WEXITSTATUS
|
||||
|
|
|
|||
16
src/script.h
16
src/script.h
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
script.h -- header file for script.c
|
||||
Copyright (C) 1999-2005 Ivo Timmermans,
|
||||
2000-2013 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2017 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,18 @@
|
|||
#ifndef __TINC_SCRIPT_H__
|
||||
#define __TINC_SCRIPT_H__
|
||||
|
||||
extern bool execute_script(const char *, char **);
|
||||
typedef struct environment {
|
||||
int n;
|
||||
int size;
|
||||
char **entries;
|
||||
} environment_t;
|
||||
|
||||
extern int environment_add(environment_t *env, const char *format, ...);
|
||||
extern int environment_placeholder(environment_t *env);
|
||||
extern void environment_update(environment_t *env, int pos, const char *format, ...);
|
||||
extern void environment_init(environment_t *env);
|
||||
extern void environment_exit(environment_t *env);
|
||||
|
||||
extern bool execute_script(const char *name, environment_t *env);
|
||||
|
||||
#endif /* __TINC_SCRIPT_H__ */
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include <sys/stropts.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <stropts.h>
|
||||
|
||||
#include "../conf.h"
|
||||
#include "../device.h"
|
||||
|
|
@ -41,6 +42,7 @@
|
|||
|
||||
#define DEFAULT_TUN_DEVICE "/dev/tun"
|
||||
#define DEFAULT_TAP_DEVICE "/dev/tap"
|
||||
#define IP_DEVICE "/dev/udp"
|
||||
|
||||
static enum {
|
||||
DEVICE_TYPE_TUN,
|
||||
|
|
@ -84,8 +86,8 @@ static bool setup_device(void) {
|
|||
|
||||
/* The following is black magic copied from OpenVPN. */
|
||||
|
||||
if((ip_fd = open("/dev/ip", O_RDWR, 0)) < 0) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s\n", "/dev/ip", strerror(errno));
|
||||
if((ip_fd = open(IP_DEVICE, O_RDWR, 0)) < 0) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s\n", IP_DEVICE, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -203,7 +205,7 @@ static bool setup_device(void) {
|
|||
|
||||
/* Push arp module to ip_fd */
|
||||
if(ioctl(ip_fd, I_PUSH, "arp") < 0) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Could not push ARP module onto %s!", "/dev/ip");
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Could not push ARP module onto %s!", IP_DEVICE);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -295,11 +297,16 @@ static void close_device(void) {
|
|||
}
|
||||
|
||||
static bool read_packet(vpn_packet_t *packet) {
|
||||
int inlen;
|
||||
int result;
|
||||
struct strbuf sbuf;
|
||||
int f = 0;
|
||||
|
||||
switch(device_type) {
|
||||
case DEVICE_TYPE_TUN:
|
||||
if((inlen = read(device_fd, DATA(packet) + 14, MTU - 14)) <= 0) {
|
||||
sbuf.maxlen = MTU - 14;
|
||||
sbuf.buf = (char *)DATA(packet) + 14;
|
||||
|
||||
if((result = getmsg(device_fd, NULL, &sbuf, &f)) < 0) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
|
@ -319,16 +326,19 @@ static bool read_packet(vpn_packet_t *packet) {
|
|||
}
|
||||
|
||||
memset(DATA(packet), 0, 12);
|
||||
packet->len = inlen + 14;
|
||||
packet->len = sbuf.len + 14;
|
||||
break;
|
||||
|
||||
case DEVICE_TYPE_TAP:
|
||||
if((inlen = read(device_fd, DATA(packet), MTU)) <= 0) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno));
|
||||
sbuf.maxlen = MTU;
|
||||
sbuf.buf = (char *)DATA(packet);
|
||||
|
||||
if((result = getmsg(device_fd, NULL, &sbuf, &f)) < 0) {
|
||||
logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
packet->len = inlen + 14;
|
||||
packet->len = sbuf.len;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -343,17 +353,25 @@ static bool read_packet(vpn_packet_t *packet) {
|
|||
static bool write_packet(vpn_packet_t *packet) {
|
||||
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", packet->len, device_info);
|
||||
|
||||
struct strbuf sbuf;
|
||||
|
||||
switch(device_type) {
|
||||
case DEVICE_TYPE_TUN:
|
||||
if(write(device_fd, DATA(packet) + 14, packet->len - 14) < 0) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno));
|
||||
sbuf.len = packet->len - 14;
|
||||
sbuf.buf = (char *)DATA(packet) + 14;
|
||||
|
||||
if(putmsg(device_fd, NULL, &sbuf, 0) < 0) {
|
||||
logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case DEVICE_TYPE_TAP:
|
||||
if(write(device_fd, DATA(packet), packet->len) < 0) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno));
|
||||
sbuf.len = packet->len;
|
||||
sbuf.buf = (char *)DATA(packet);
|
||||
|
||||
if(putmsg(device_fd, NULL, &sbuf, 0) < 0) {
|
||||
logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ static bool readonly;
|
|||
static bool writeonly;
|
||||
static int in = 0;
|
||||
static int out = 1;
|
||||
static int addressfamily = AF_UNSPEC;
|
||||
|
||||
static bool send_data(void *handle, uint8_t type, const void *data, size_t len) {
|
||||
char hex[len * 2 + 1];
|
||||
|
|
@ -58,7 +59,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) {
|
||||
if(verbose)
|
||||
fprintf(stderr, "Received type %d record of %hu bytes:\n", type, len);
|
||||
fprintf(stderr, "Received type %d record of %u bytes:\n", type, len);
|
||||
if(!writeonly)
|
||||
write(out, data, len);
|
||||
return true;
|
||||
|
|
@ -93,6 +94,8 @@ static void usage() {
|
|||
" -R, --replay-window N Set replay window to N bytes.\n"
|
||||
" -s, --special Enable special handling of lines starting with #, ^ and $.\n"
|
||||
" -v, --verbose Display debug messages.\n"
|
||||
" -4 Use IPv4.\n"
|
||||
" -6 Use IPv6.\n"
|
||||
"\n");
|
||||
fprintf(stderr, "Report bugs to tinc@tinc-vpn.org.\n");
|
||||
}
|
||||
|
|
@ -110,7 +113,7 @@ int main(int argc, char *argv[]) {
|
|||
ecdsa_t *mykey = NULL, *hiskey = NULL;
|
||||
bool quit = false;
|
||||
|
||||
while((r = getopt_long(argc, argv, "dqrstwL:W:v", long_options, &option_index)) != EOF) {
|
||||
while((r = getopt_long(argc, argv, "dqrstwL:W:v46", long_options, &option_index)) != EOF) {
|
||||
switch (r) {
|
||||
case 0: /* long option */
|
||||
break;
|
||||
|
|
@ -161,6 +164,14 @@ int main(int argc, char *argv[]) {
|
|||
usage();
|
||||
return 1;
|
||||
|
||||
case '4': /* IPv4 */
|
||||
addressfamily = AF_INET;
|
||||
break;
|
||||
|
||||
case '6': /* IPv6 */
|
||||
addressfamily = AF_INET6;
|
||||
break;
|
||||
|
||||
case 1: /* help */
|
||||
usage();
|
||||
return 0;
|
||||
|
|
@ -212,7 +223,7 @@ int main(int argc, char *argv[]) {
|
|||
struct addrinfo *ai, hint;
|
||||
memset(&hint, 0, sizeof hint);
|
||||
|
||||
hint.ai_family = AF_UNSPEC;
|
||||
hint.ai_family = addressfamily;
|
||||
hint.ai_socktype = datagram ? SOCK_DGRAM : SOCK_STREAM;
|
||||
hint.ai_protocol = datagram ? IPPROTO_UDP : IPPROTO_TCP;
|
||||
hint.ai_flags = initiator ? 0 : AI_PASSIVE;
|
||||
|
|
|
|||
35
src/subnet.c
35
src/subnet.c
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
subnet.c -- handle subnet lookups and lists
|
||||
Copyright (C) 2000-2013 Guus Sliepen <guus@tinc-vpn.org>,
|
||||
Copyright (C) 2000-2017 Guus Sliepen <guus@tinc-vpn.org>,
|
||||
2000-2005 Ivo Timmermans
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
|
@ -206,22 +206,20 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) {
|
|||
|
||||
// Prepare environment variables to be passed to the script
|
||||
|
||||
char *envp[10] = {NULL};
|
||||
int n = 0;
|
||||
xasprintf(&envp[n++], "NETNAME=%s", netname ? : "");
|
||||
xasprintf(&envp[n++], "DEVICE=%s", device ? : "");
|
||||
xasprintf(&envp[n++], "INTERFACE=%s", iface ? : "");
|
||||
xasprintf(&envp[n++], "NODE=%s", owner->name);
|
||||
environment_t env;
|
||||
environment_init(&env);
|
||||
environment_add(&env, "NODE=%s", owner->name);
|
||||
|
||||
if(owner != myself) {
|
||||
sockaddr2str(&owner->address, &address, &port);
|
||||
xasprintf(&envp[n++], "REMOTEADDRESS=%s", address);
|
||||
xasprintf(&envp[n++], "REMOTEPORT=%s", port);
|
||||
environment_add(&env, "REMOTEADDRESS=%s", address);
|
||||
environment_add(&env, "REMOTEPORT=%s", port);
|
||||
free(port);
|
||||
free(address);
|
||||
}
|
||||
|
||||
xasprintf(&envp[n++], "NAME=%s", myself->name);
|
||||
int env_subnet = environment_add(&env, NULL);
|
||||
int env_weight = environment_add(&env, NULL);
|
||||
|
||||
name = up ? "subnet-up" : "subnet-down";
|
||||
|
||||
|
|
@ -238,12 +236,10 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) {
|
|||
weight = empty;
|
||||
|
||||
// Prepare the SUBNET and WEIGHT variables
|
||||
free(envp[n]);
|
||||
free(envp[n + 1]);
|
||||
xasprintf(&envp[n], "SUBNET=%s", netstr);
|
||||
xasprintf(&envp[n + 1], "WEIGHT=%s", weight);
|
||||
environment_update(&env, env_subnet, "SUBNET=%s", netstr);
|
||||
environment_update(&env, env_weight, "WEIGHT=%s", weight);
|
||||
|
||||
execute_script(name, envp);
|
||||
execute_script(name, &env);
|
||||
}
|
||||
} else {
|
||||
if(net2str(netstr, sizeof netstr, subnet)) {
|
||||
|
|
@ -255,15 +251,14 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) {
|
|||
weight = empty;
|
||||
|
||||
// Prepare the SUBNET and WEIGHT variables
|
||||
xasprintf(&envp[n], "SUBNET=%s", netstr);
|
||||
xasprintf(&envp[n + 1], "WEIGHT=%s", weight);
|
||||
environment_update(&env, env_subnet, "SUBNET=%s", netstr);
|
||||
environment_update(&env, env_weight, "WEIGHT=%s", weight);
|
||||
|
||||
execute_script(name, envp);
|
||||
execute_script(name, &env);
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; envp[i] && i < 9; i++)
|
||||
free(envp[i]);
|
||||
environment_exit(&env);
|
||||
}
|
||||
|
||||
bool dump_subnets(connection_t *c) {
|
||||
|
|
|
|||
|
|
@ -372,7 +372,7 @@ bool net2str(char *netstr, int len, const subnet_t *subnet) {
|
|||
result = snprintf(netstr, len, *format, ":::");
|
||||
i += max_zero_length;
|
||||
} else {
|
||||
result = snprintf(netstr, len, "%hx:", ntohs(subnet->net.ipv6.address.x[i]));
|
||||
result = snprintf(netstr, len, "%x:", ntohs(subnet->net.ipv6.address.x[i]));
|
||||
i++;
|
||||
}
|
||||
netstr += result;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
tincctl.c -- Controlling a running tincd
|
||||
Copyright (C) 2007-2016 Guus Sliepen <guus@tinc-vpn.org>
|
||||
Copyright (C) 2007-2017 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
|
||||
|
|
@ -74,6 +74,9 @@ bool netnamegiven = false;
|
|||
char *scriptinterpreter = NULL;
|
||||
char *scriptextension = "";
|
||||
static char *prompt;
|
||||
char *device = NULL;
|
||||
char *iface = NULL;
|
||||
int debug_level = -1;
|
||||
|
||||
static struct option const long_options[] = {
|
||||
{"batch", no_argument, NULL, 'b'},
|
||||
|
|
@ -89,7 +92,7 @@ static struct option const long_options[] = {
|
|||
static void version(void) {
|
||||
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-2016 Ivo Timmermans, Guus Sliepen and others.\n"
|
||||
printf("Copyright (C) 1998-2017 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"
|
||||
|
|
@ -446,11 +449,13 @@ static bool rsa_keygen(int bits, bool ask) {
|
|||
// Make sure the key size is a multiple of 8 bits.
|
||||
bits &= ~0x7;
|
||||
|
||||
// Force them to be between 1024 and 8192 bits long.
|
||||
if(bits < 1024)
|
||||
bits = 1024;
|
||||
if(bits > 8192)
|
||||
bits = 8192;
|
||||
// Make sure that a valid key size is used.
|
||||
if(bits < 1024 || bits > 8192) {
|
||||
fprintf(stderr, "Invalid key size %d specified! It should be between 1024 and 8192 bits.\n", bits);
|
||||
return false;
|
||||
} else if(bits < 2048) {
|
||||
fprintf(stderr, "WARNING: generating a weak %d bits RSA key! 2048 or more bits are recommended.\n", bits);
|
||||
}
|
||||
|
||||
fprintf(stderr, "Generating %d bits keys:\n", bits);
|
||||
|
||||
|
|
@ -508,7 +513,7 @@ bool recvline(int fd, char *line, size_t len) {
|
|||
char *newline = NULL;
|
||||
|
||||
if(!fd)
|
||||
abort();
|
||||
return false;
|
||||
|
||||
while(!(newline = memchr(buffer, '\n', blen))) {
|
||||
int result = recv(fd, buffer + blen, sizeof buffer - blen, 0);
|
||||
|
|
@ -719,6 +724,8 @@ bool connect_tincd(bool verbose) {
|
|||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
#ifndef HAVE_MINGW
|
||||
if ((pid == 0) || (kill(pid, 0) && (errno == ESRCH))) {
|
||||
fprintf(stderr, "Could not find tincd running at pid %d\n", pid);
|
||||
/* clean up the stale socket and pid file */
|
||||
|
|
@ -727,7 +734,6 @@ bool connect_tincd(bool verbose) {
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifndef HAVE_MINGW
|
||||
struct sockaddr_un sa;
|
||||
sa.sun_family = AF_UNIX;
|
||||
strncpy(sa.sun_path, unixsocketname, sizeof sa.sun_path);
|
||||
|
|
@ -797,7 +803,7 @@ bool connect_tincd(bool verbose) {
|
|||
char data[4096];
|
||||
int version;
|
||||
|
||||
if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %s %d", &code, data, &version) != 3 || code != 0) {
|
||||
if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %4095s %d", &code, data, &version) != 3 || code != 0) {
|
||||
if(verbose)
|
||||
fprintf(stderr, "Cannot read greeting from control socket: %s\n", sockstrerror(sockerrno));
|
||||
close(fd);
|
||||
|
|
@ -945,11 +951,11 @@ static int cmd_stop(int argc, char *argv[]) {
|
|||
if(!connect_tincd(true)) {
|
||||
if(pid) {
|
||||
if(kill(pid, SIGTERM)) {
|
||||
fprintf(stderr, "Could not send TERM signal to process with PID %u: %s\n", pid, strerror(errno));
|
||||
fprintf(stderr, "Could not send TERM signal to process with PID %d: %s\n", pid, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Sent TERM signal to process with PID %u.\n", pid);
|
||||
fprintf(stderr, "Sent TERM signal to process with PID %d.\n", pid);
|
||||
waitpid(pid, NULL, 0);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1024,7 +1030,6 @@ static int dump_invitations(void) {
|
|||
FILE *f = fopen(fname, "r");
|
||||
if(!f) {
|
||||
fprintf(stderr, "Cannot open %s: %s\n", fname, strerror(errno));
|
||||
fclose(f);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1113,7 +1118,7 @@ static int cmd_dump(int argc, char *argv[]) {
|
|||
|
||||
while(recvline(fd, line, sizeof line)) {
|
||||
char node1[4096], node2[4096];
|
||||
int n = sscanf(line, "%d %d %s %s", &code, &req, node1, node2);
|
||||
int n = sscanf(line, "%d %d %4095s %4095s", &code, &req, node1, node2);
|
||||
if(n == 2) {
|
||||
if(do_graph && req == REQ_DUMP_NODES)
|
||||
continue;
|
||||
|
|
@ -1145,7 +1150,7 @@ static int cmd_dump(int argc, char *argv[]) {
|
|||
|
||||
switch(req) {
|
||||
case REQ_DUMP_NODES: {
|
||||
int n = sscanf(line, "%*d %*d %s %s %s port %s %d %d %d %d %x %x %s %s %d %hd %hd %hd %ld", node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_int, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change);
|
||||
int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %d %d %d %d %x %x %4095s %4095s %d %hd %hd %hd %ld", node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_int, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change);
|
||||
if(n != 17) {
|
||||
fprintf(stderr, "Unable to parse node dump from tincd: %s\n", line);
|
||||
return 1;
|
||||
|
|
@ -1169,13 +1174,13 @@ static int cmd_dump(int argc, char *argv[]) {
|
|||
} else {
|
||||
if(only_reachable && !status.reachable)
|
||||
continue;
|
||||
printf("%s id %s at %s port %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %hd (min %hd max %hd)\n",
|
||||
printf("%s id %s at %s port %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %d (min %d max %d)\n",
|
||||
node, id, host, port, cipher, digest, maclength, compression, options, status_int, nexthop, via, distance, pmtu, minmtu, maxmtu);
|
||||
}
|
||||
} break;
|
||||
|
||||
case REQ_DUMP_EDGES: {
|
||||
int n = sscanf(line, "%*d %*d %s %s %s port %s %s port %s %x %d", from, to, host, port, local_host, local_port, &options, &weight);
|
||||
int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %4095s port %4095s %x %d", from, to, host, port, local_host, local_port, &options, &weight);
|
||||
if(n != 8) {
|
||||
fprintf(stderr, "Unable to parse edge dump from tincd.\n");
|
||||
return 1;
|
||||
|
|
@ -1193,7 +1198,7 @@ static int cmd_dump(int argc, char *argv[]) {
|
|||
} break;
|
||||
|
||||
case REQ_DUMP_SUBNETS: {
|
||||
int n = sscanf(line, "%*d %*d %s %s", subnet, node);
|
||||
int n = sscanf(line, "%*d %*d %4095s %4095s", subnet, node);
|
||||
if(n != 2) {
|
||||
fprintf(stderr, "Unable to parse subnet dump from tincd.\n");
|
||||
return 1;
|
||||
|
|
@ -1202,7 +1207,7 @@ static int cmd_dump(int argc, char *argv[]) {
|
|||
} break;
|
||||
|
||||
case REQ_DUMP_CONNECTIONS: {
|
||||
int n = sscanf(line, "%*d %*d %s %s port %s %x %d %x", node, host, port, &options, &socket, &status_int);
|
||||
int n = sscanf(line, "%*d %*d %4095s %4095s port %4095s %x %d %x", node, host, port, &options, &socket, &status_int);
|
||||
if(n != 6) {
|
||||
fprintf(stderr, "Unable to parse connection dump from tincd.\n");
|
||||
return 1;
|
||||
|
|
@ -1485,9 +1490,11 @@ const var_t variables[] = {
|
|||
{"Hostnames", VAR_SERVER},
|
||||
{"IffOneQueue", VAR_SERVER},
|
||||
{"Interface", VAR_SERVER},
|
||||
{"InvitationExpire", VAR_SERVER},
|
||||
{"KeyExpire", VAR_SERVER},
|
||||
{"ListenAddress", VAR_SERVER | VAR_MULTIPLE},
|
||||
{"LocalDiscovery", VAR_SERVER},
|
||||
{"LogLevel", VAR_SERVER},
|
||||
{"MACExpire", VAR_SERVER},
|
||||
{"MaxConnectionBurst", VAR_SERVER},
|
||||
{"MaxOutputBufferSize", VAR_SERVER},
|
||||
|
|
@ -2227,7 +2234,7 @@ static int cmd_import(int argc, char *argv[]) {
|
|||
bool firstline = true;
|
||||
|
||||
while(fgets(buf, sizeof buf, in)) {
|
||||
if(sscanf(buf, "Name = %s", name) == 1) {
|
||||
if(sscanf(buf, "Name = %4095s", name) == 1) {
|
||||
firstline = false;
|
||||
|
||||
if(!check_id(name)) {
|
||||
|
|
@ -2719,7 +2726,7 @@ static char *complete_info(const char *text, int state) {
|
|||
|
||||
while(recvline(fd, line, sizeof line)) {
|
||||
char item[4096];
|
||||
int n = sscanf(line, "%d %d %s", &code, &req, item);
|
||||
int n = sscanf(line, "%d %d %4095s", &code, &req, item);
|
||||
if(n == 2) {
|
||||
i++;
|
||||
if(i >= 2)
|
||||
|
|
@ -2820,8 +2827,6 @@ static int cmd_shell(int argc, char *argv[]) {
|
|||
|
||||
while(p && *p) {
|
||||
if(nargc >= maxargs) {
|
||||
fprintf(stderr, "next %p '%s', p %p '%s'\n", next, next, p, p);
|
||||
abort();
|
||||
maxargs *= 2;
|
||||
nargv = xrealloc(nargv, maxargs * sizeof *nargv);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -400,6 +400,9 @@ int main(int argc, char **argv) {
|
|||
if(!read_server_config())
|
||||
return 1;
|
||||
|
||||
if(!debug_level)
|
||||
get_config_int(lookup_config(config_tree, "LogLevel"), &debug_level);
|
||||
|
||||
#ifdef HAVE_LZO
|
||||
if(lzo_init() != LZO_E_OK) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error initializing LZO compressor!");
|
||||
|
|
|
|||
42
src/top.c
42
src/top.c
|
|
@ -90,7 +90,7 @@ static bool update(int fd) {
|
|||
ns->known = false;
|
||||
|
||||
while(recvline(fd, line, sizeof line)) {
|
||||
int n = sscanf(line, "%d %d %s %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, &code, &req, name, &in_packets, &in_bytes, &out_packets, &out_bytes);
|
||||
int n = sscanf(line, "%d %d %4095s %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, &code, &req, name, &in_packets, &in_bytes, &out_packets, &out_bytes);
|
||||
|
||||
if(n == 2)
|
||||
return true;
|
||||
|
|
@ -158,40 +158,54 @@ static int cmpu64(uint64_t a, uint64_t b) {
|
|||
static int sortfunc(const void *a, const void *b) {
|
||||
const nodestats_t *na = *(const nodestats_t **)a;
|
||||
const nodestats_t *nb = *(const nodestats_t **)b;
|
||||
int result;
|
||||
|
||||
switch(sortmode) {
|
||||
case 1:
|
||||
if(cumulative)
|
||||
return -cmpu64(na->in_packets, nb->in_packets) ?: na->i - nb->i;
|
||||
result = -cmpu64(na->in_packets, nb->in_packets);
|
||||
else
|
||||
return -cmpfloat(na->in_packets_rate, nb->in_packets_rate) ?: na->i - nb->i;
|
||||
result = -cmpfloat(na->in_packets_rate, nb->in_packets_rate);
|
||||
break;
|
||||
case 2:
|
||||
if(cumulative)
|
||||
return -cmpu64(na->in_bytes, nb->in_bytes) ?: na->i - nb->i;
|
||||
result = -cmpu64(na->in_bytes, nb->in_bytes);
|
||||
else
|
||||
return -cmpfloat(na->in_bytes_rate, nb->in_bytes_rate) ?: na->i - nb->i;
|
||||
result = -cmpfloat(na->in_bytes_rate, nb->in_bytes_rate);
|
||||
break;
|
||||
case 3:
|
||||
if(cumulative)
|
||||
return -cmpu64(na->out_packets, nb->out_packets) ?: na->i - nb->i;
|
||||
result = -cmpu64(na->out_packets, nb->out_packets);
|
||||
else
|
||||
return -cmpfloat(na->out_packets_rate, nb->out_packets_rate) ?: na->i - nb->i;
|
||||
result = -cmpfloat(na->out_packets_rate, nb->out_packets_rate);
|
||||
break;
|
||||
case 4:
|
||||
if(cumulative)
|
||||
return -cmpu64(na->out_bytes, nb->out_bytes) ?: na->i - nb->i;
|
||||
result = -cmpu64(na->out_bytes, nb->out_bytes);
|
||||
else
|
||||
return -cmpfloat(na->out_bytes_rate, nb->out_bytes_rate) ?: na->i - nb->i;
|
||||
result = -cmpfloat(na->out_bytes_rate, nb->out_bytes_rate);
|
||||
break;
|
||||
case 5:
|
||||
if(cumulative)
|
||||
return -cmpu64(na->in_packets + na->out_packets, nb->in_packets + nb->out_packets) ?: na->i - nb->i;
|
||||
result = -cmpu64(na->in_packets + na->out_packets, nb->in_packets + nb->out_packets);
|
||||
else
|
||||
return -cmpfloat(na->in_packets_rate + na->out_packets_rate, nb->in_packets_rate + nb->out_packets_rate) ?: na->i - nb->i;
|
||||
result = -cmpfloat(na->in_packets_rate + na->out_packets_rate, nb->in_packets_rate + nb->out_packets_rate);
|
||||
break;
|
||||
case 6:
|
||||
if(cumulative)
|
||||
return -cmpu64(na->in_bytes + na->out_bytes, nb->in_bytes + nb->out_bytes) ?: na->i - nb->i;
|
||||
result = -cmpu64(na->in_bytes + na->out_bytes, nb->in_bytes + nb->out_bytes);
|
||||
else
|
||||
return -cmpfloat(na->in_bytes_rate + na->out_bytes_rate, nb->in_bytes_rate + nb->out_bytes_rate) ?: na->i - nb->i;
|
||||
result = -cmpfloat(na->in_bytes_rate + na->out_bytes_rate, nb->in_bytes_rate + nb->out_bytes_rate);
|
||||
break;
|
||||
default:
|
||||
return strcmp(na->name, nb->name) ?: na->i - nb->i;
|
||||
result = strcmp(na->name, nb->name);
|
||||
break;
|
||||
}
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
else
|
||||
return na->i - nb->i;
|
||||
}
|
||||
|
||||
static void redraw(void) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
device.c -- UML network socket
|
||||
Copyright (C) 2002-2005 Ivo Timmermans,
|
||||
2002-2013 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2002-2017 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
|
||||
|
|
@ -228,7 +228,7 @@ static bool read_packet(vpn_packet_t *packet) {
|
|||
return false;
|
||||
}
|
||||
|
||||
if(connect(write_fd, &request.sock, sizeof request.sock) < 0) {
|
||||
if(connect(write_fd, (struct sockkadr *)&request.sock, sizeof request.sock) < 0) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind write %s: %s", device_info, strerror(errno));
|
||||
event_exit();
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ static struct UPNPDev *upnp_discover(int delay, int *error) {
|
|||
|
||||
#elif MINIUPNPC_API_VERSION <= 14
|
||||
|
||||
return upnpDiscover(delay, NULL NULL, false, false, 2, error);
|
||||
return upnpDiscover(delay, NULL, NULL, false, false, 2, error);
|
||||
|
||||
#else
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue