Import Upstream version 1.1~pre17

This commit is contained in:
Guus Sliepen 2019-08-26 13:44:53 +02:00
parent bc8ca65653
commit b511a112e6
216 changed files with 43313 additions and 18448 deletions

View file

@ -6,9 +6,10 @@ TESTS = \
invite-join.test \
invite-offline.test \
invite-tinc-up.test \
legacy-protocol.test \
ns-ping.test \
ping.test \
scripts.test \
security.test \
sptps-basic.test \
variables.test
@ -16,12 +17,14 @@ dist_check_SCRIPTS = $(TESTS)
EXTRA_DIST = testlib.sh
check_PROGRAMS = pong
AM_CFLAGS = -iquote.
pong_SOURCES = pong.c
check_PROGRAMS = \
splice
splice_SOURCES = splice.c
clean-local:
-for pid in *.test.?/pid; do ../src/tinc --pidfile="$$pid" stop; done
-killall ../src/sptps_test
-killall pong
-rm -rf *.test.?

View file

@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.15.1 from Makefile.am.
# Makefile.in generated by automake 1.16.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2017 Free Software Foundation, Inc.
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -87,7 +87,7 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
check_PROGRAMS = pong$(EXEEXT)
check_PROGRAMS = splice$(EXEEXT)
subdir = test
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
@ -95,6 +95,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
$(top_srcdir)/m4/ax_cflags_warn_all.m4 \
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
$(top_srcdir)/m4/ax_check_link_flag.m4 \
$(top_srcdir)/m4/ax_code_coverage.m4 \
$(top_srcdir)/m4/ax_require_defined.m4 \
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \
$(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \
@ -108,9 +109,9 @@ mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am_pong_OBJECTS = pong.$(OBJEXT)
pong_OBJECTS = $(am_pong_OBJECTS)
pong_LDADD = $(LDADD)
am_splice_OBJECTS = splice.$(OBJEXT)
splice_OBJECTS = $(am_splice_OBJECTS)
splice_LDADD = $(LDADD)
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
@ -125,7 +126,8 @@ am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES =
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__maybe_remake_depfiles = depfiles
am__depfiles_remade = ./$(DEPDIR)/splice.Po
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@ -139,8 +141,8 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(pong_SOURCES)
DIST_SOURCES = $(pong_SOURCES)
SOURCES = $(splice_SOURCES)
DIST_SOURCES = $(splice_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
@ -380,6 +382,12 @@ AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@
CODE_COVERAGE_CPPFLAGS = @CODE_COVERAGE_CPPFLAGS@
CODE_COVERAGE_CXXFLAGS = @CODE_COVERAGE_CXXFLAGS@
CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@
CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@
CODE_COVERAGE_LIBS = @CODE_COVERAGE_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CURSES_LIBS = @CURSES_LIBS@
@ -391,16 +399,18 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GCOV = @GCOV@
GENHTML = @GENHTML@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LCOV = @LCOV@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MINIUPNPC_LIBS = @MINIUPNPC_LIBS@
@ -415,6 +425,7 @@ PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
READLINE_LIBS = @READLINE_LIBS@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
@ -479,15 +490,17 @@ TESTS = \
invite-join.test \
invite-offline.test \
invite-tinc-up.test \
legacy-protocol.test \
ns-ping.test \
ping.test \
scripts.test \
security.test \
sptps-basic.test \
variables.test
dist_check_SCRIPTS = $(TESTS)
EXTRA_DIST = testlib.sh
pong_SOURCES = pong.c
AM_CFLAGS = -iquote.
splice_SOURCES = splice.c
all: all-am
.SUFFIXES:
@ -509,8 +522,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@ -525,9 +538,9 @@ $(am__aclocal_m4_deps):
clean-checkPROGRAMS:
-test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS)
pong$(EXEEXT): $(pong_OBJECTS) $(pong_DEPENDENCIES) $(EXTRA_pong_DEPENDENCIES)
@rm -f pong$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(pong_OBJECTS) $(pong_LDADD) $(LIBS)
splice$(EXEEXT): $(splice_OBJECTS) $(splice_DEPENDENCIES) $(EXTRA_splice_DEPENDENCIES)
@rm -f splice$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(splice_OBJECTS) $(splice_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@ -535,7 +548,13 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pong.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/splice.Po@am__quote@ # am--include-marker
$(am__depfiles_remade):
@$(MKDIR_P) $(@D)
@echo '# dummy' >$@-t && $(am__mv) $@-t $@
am--depfiles: $(am__depfiles_remade)
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@ -725,7 +744,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
fi; \
$$success || exit 1
check-TESTS:
check-TESTS: $(check_PROGRAMS) $(dist_check_SCRIPTS)
@list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
@ -761,7 +780,10 @@ recheck: all $(check_PROGRAMS) $(dist_check_SCRIPTS)
@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
distdir: $(DISTFILES)
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
@ -836,7 +858,7 @@ clean: clean-am
clean-am: clean-checkPROGRAMS clean-generic clean-local mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f ./$(DEPDIR)/splice.Po
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
@ -882,7 +904,7 @@ install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f ./$(DEPDIR)/splice.Po
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
@ -902,18 +924,19 @@ uninstall-am:
.MAKE: check-am install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
clean-checkPROGRAMS clean-generic clean-local 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-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \
recheck tags tags-am uninstall uninstall-am
.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
check-am clean clean-checkPROGRAMS clean-generic clean-local \
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-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic pdf pdf-am ps ps-am recheck tags tags-am \
uninstall uninstall-am
.PRECIOUS: Makefile
@ -921,7 +944,6 @@ uninstall-am:
clean-local:
-for pid in *.test.?/pid; do ../src/tinc --pidfile="$$pid" stop; done
-killall ../src/sptps_test
-killall pong
-rm -rf *.test.?
# Tell versions [3.59,3.63) of GNU make to not export all variables.

View file

@ -1,6 +1,6 @@
#!/bin/sh
. ./testlib.sh
. "${0%/*}/testlib.sh"
# Initialize and test one node

View file

@ -1,6 +1,6 @@
#!/bin/sh
. ./testlib.sh
. "${0%/*}/testlib.sh"
# Initialize one node

View file

@ -1,6 +1,6 @@
#!/bin/sh
. ./testlib.sh
. "${0%/*}/testlib.sh"
# Just test whether the executables work
$tincd --help

View file

@ -1,6 +1,6 @@
#!/bin/sh
. ./testlib.sh
. "${0%/*}/testlib.sh"
# Initialize three nodes

View file

@ -1,6 +1,6 @@
#!/bin/sh
. ./testlib.sh
. "${0%/*}/testlib.sh"
# Initialize one node
@ -9,7 +9,6 @@ init foo
set DeviceType dummy
set Mode switch
set Broadcast no
del Port
set Address localhost
set Port 32751
start $r1

View file

@ -1,6 +1,6 @@
#!/bin/sh
. ./testlib.sh
. "${0%/*}/testlib.sh"
# Initialize one node
@ -9,7 +9,6 @@ init foo
set DeviceType dummy
set Mode switch
set Broadcast no
del Port
set Address localhost
set Port 32758
EOF

View file

@ -1,6 +1,6 @@
#!/bin/sh
. ./testlib.sh
. "${0%/*}/testlib.sh"
# Initialize one node

79
test/legacy-protocol.test Executable file
View file

@ -0,0 +1,79 @@
#!/bin/sh
. "${0%/*}/testlib.sh"
# Initialize two nodes
$tinc $c1 <<EOF
init foo
set DeviceType dummy
set Port 32753
set Address localhost
set PingTimeout 1
EOF
$tinc $c2 <<EOF
init bar
set DeviceType dummy
set Port 0
set PingTimeout 1
set MaxTimeout 1
EOF
# Exchange host config files
$tinc $c1 export | $tinc $c2 exchange | $tinc $c1 import
$tinc $c2 add ConnectTo foo
# Foo 1.1, bar 1.0
$tinc $c2 set ExperimentalProtocol no
$tinc $c1 del bar.Ed25519PublicKey
$tinc $c2 del foo.Ed25519PublicKey
$tinc $c1 start $r1
$tinc $c2 start $r2
sleep 1
test `$tinc $c1 dump reachable nodes | wc -l` = 2
test `$tinc $c2 dump reachable nodes | wc -l` = 2
$tinc $c2 stop
$tinc $c1 stop
test -z "`$tinc $c1 get bar.Ed25519PublicKey`"
test -z "`$tinc $c2 get foo.Ed25519PublicKey`"
# Foo 1.1, bar upgrades to 1.1
$tinc $c2 del ExperimentalProtocol
$tinc $c1 start $r1
$tinc $c2 start $r2
sleep 5
test `$tinc $c1 dump reachable nodes | wc -l` = 2
test `$tinc $c2 dump reachable nodes | wc -l` = 2
$tinc $c2 stop
$tinc $c1 stop
test -n "`$tinc $c1 get bar.Ed25519PublicKey`"
test -n "`$tinc $c2 get foo.Ed25519PublicKey`"
# Bar downgrades, must no longer be allowed to connect
$tinc $c2 set ExperimentalProtocol no
$tinc $c1 start $r1
$tinc $c2 start $r2
sleep 1
test `$tinc $c1 dump reachable nodes | wc -l` = 1
test `$tinc $c2 dump reachable nodes | wc -l` = 1
$tinc $c2 stop
$tinc $c1 stop

View file

@ -1,6 +1,6 @@
#!/bin/sh
. ./testlib.sh
. "${0%/*}/testlib.sh"
# Skip this test if we aren't root or if "ip netns" does not exist

View file

@ -1,58 +0,0 @@
#!/bin/sh
. ./testlib.sh
# Skip this test if we aren't root
test "`id -u`" = "0" || exit 77
# Initialize two nodes
$tinc $c1 <<EOF
init foo
set Mode switch
set Interface ping.test
set Port 32573
set Address localhost
EOF
cat >$d1/tinc-up <<EOF
#!/bin/sh
ifconfig \$INTERFACE up
EOF
$tinc $c2 <<EOF
init bar
set Mode switch
set DeviceType multicast
set Device 233.252.0.1 32754
add ConnectTo foo
EOF
# Exchange configuration files
$tinc $c1 export | $tinc $c2 exchange | $tinc $c1 import
# Ensure we have a working multicast route
ip route replace 233.252.0.0/16 dev lo
# Start pong program in background
./pong 233.252.0.1 32754 10.6.5.5 &
pong=$!
# Start tinc and try to ping
$tinc $c1 start $r1
$tinc $c2 start $r2
sleep 1
ping -r -I ping.test -c3 10.6.5.5
# Clean up
kill $pong
$tinc $c2 stop
$tinc $c1 stop

View file

@ -1,196 +0,0 @@
/*
pong.c -- ICMP echo reply generator
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
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 "../src/system.h"
#include "../src/ethernet.h"
uint8_t mymac[6] = {6, 5, 5, 6, 5, 5};
static ssize_t do_arp(uint8_t *buf, ssize_t len, struct sockaddr_in *in) {
struct ether_arp arp;
memcpy(&arp, buf + 14, sizeof arp);
// Is it a valid ARP request?
if(ntohs(arp.arp_hrd) != ARPHRD_ETHER || ntohs(arp.arp_pro) != ETH_P_IP || arp.arp_hln != ETH_ALEN || arp.arp_pln != sizeof in->sin_addr.s_addr || ntohs(arp.arp_op) != ARPOP_REQUEST)
return 0;
// Does it match our address?
if(memcmp(&in->sin_addr.s_addr, arp.arp_tpa, 4))
return 0;
// Swap addresses
memcpy(buf, buf + 6, 6);
memcpy(buf + 6, mymac, 6);
arp.arp_op = htons(ARPOP_REPLY);
memcpy(arp.arp_tpa, arp.arp_spa, sizeof arp.arp_tpa);
memcpy(arp.arp_tha, arp.arp_sha, sizeof arp.arp_tha);
memcpy(arp.arp_spa, &in->sin_addr.s_addr, sizeof in->sin_addr.s_addr);
memcpy(arp.arp_sha, mymac, 6);
memcpy(buf + 14, &arp, sizeof arp);
return len;
}
static ssize_t do_ipv4(uint8_t *buf, ssize_t len, struct sockaddr_in *in) {
struct ip ip;
struct icmp icmp;
// Does it match our address?
if(memcmp(buf, mymac, 6))
return 0;
memcpy(&ip, buf + 14, sizeof ip);
if(memcmp(&ip.ip_dst, &in->sin_addr.s_addr, 4))
return 0;
// Is it an ICMP echo request?
if(ip.ip_p != IPPROTO_ICMP)
return 0;
memcpy(&icmp, buf + 14 + sizeof ip, sizeof icmp);
if(icmp.icmp_type != ICMP_ECHO)
return 0;
// Return an echo reply
memcpy(buf, buf + 6, 6);
memcpy(buf + 6, mymac, 6);
ip.ip_dst = ip.ip_src;
memcpy(&ip.ip_src, &in->sin_addr.s_addr, 4);
icmp.icmp_type = ICMP_ECHOREPLY;
memcpy(buf + 14, &ip, sizeof ip);
memcpy(buf + 14 + sizeof ip, &icmp, sizeof icmp);
return len;
}
static ssize_t do_ipv6(uint8_t *buf, ssize_t len, struct sockaddr_in6 *in) {
return 0;
}
int main(int argc, char *argv[]) {
if(argc != 4) {
fprintf(stderr, "Usage: %s <multicast address> <port> <ping address>\n", argv[0]);
return 1;
}
struct addrinfo hints = {}, *ai = NULL;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_ADDRCONFIG;
errno = ENOENT;
if(getaddrinfo(argv[1], argv[2], &hints, &ai) || !ai) {
fprintf(stderr, "Could not resolve %s port %s: %s\n", argv[1], argv[2], strerror(errno));
return 1;
}
int fd;
fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if(!fd) {
fprintf(stderr, "Could not create socket: %s\n", strerror(errno));
return 1;
}
static const int one = 1;
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof one);
if(bind(fd, ai->ai_addr, ai->ai_addrlen)) {
fprintf(stderr, "Could not bind socket: %s\n", strerror(errno));
return 1;
}
switch(ai->ai_family) {
case AF_INET: {
struct ip_mreq mreq;
struct sockaddr_in in;
memcpy(&in, ai->ai_addr, sizeof in);
mreq.imr_multiaddr.s_addr = in.sin_addr.s_addr;
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
if(setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&mreq, sizeof mreq)) {
fprintf(stderr, "Cannot join multicast group: %s\n", strerror(errno));
return 1;
}
#ifdef IP_MULTICAST_LOOP
setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, (const void *)&one, sizeof one);
#endif
} break;
#ifdef IPV6_JOIN_GROUP
case AF_INET6: {
struct ipv6_mreq mreq;
struct sockaddr_in6 in6;
memcpy(&in6, ai->ai_addr, sizeof in6);
memcpy(&mreq.ipv6mr_multiaddr, &in6.sin6_addr, sizeof mreq.ipv6mr_multiaddr);
mreq.ipv6mr_interface = in6.sin6_scope_id;
if(setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, (void *)&mreq, sizeof mreq)) {
fprintf(stderr, "Cannot join multicast group: %s\n", strerror(errno));
return 1;
}
#ifdef IPV6_MULTICAST_LOOP
setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (const void *)&one, sizeof one);
#endif
} break;
#endif
default:
fprintf(stderr, "Multicast for address family %x unsupported\n", ai->ai_family);
return 1;
}
errno = ENOENT;
struct addrinfo *ai2 = NULL;
if(getaddrinfo(argv[3], NULL, &hints, &ai2) || !ai2) {
fprintf(stderr, "Could not resolve %s: %s\n", argv[3], strerror(errno));
return 1;
}
while(true) {
uint8_t buf[10000];
struct sockaddr src;
socklen_t srclen;
ssize_t len = recvfrom(fd, buf, sizeof buf, 0, &src, &srclen);
if(len <= 0)
break;
// Ignore short packets.
if(len < 14)
continue;
uint16_t type = buf[12] << 8 | buf[13];
if(ai2->ai_family == AF_INET && type == ETH_P_IP)
len = do_ipv4(buf, len, (struct sockaddr_in *)ai2->ai_addr);
else if(ai2->ai_family == AF_INET && type == ETH_P_ARP)
len = do_arp(buf, len, (struct sockaddr_in *)ai2->ai_addr);
else if(ai2->ai_family == AF_INET6 && type == ETH_P_IPV6)
len = do_ipv6(buf, len, (struct sockaddr_in6 *)ai2->ai_addr);
else
continue;
if(len > 0)
sendto(fd, buf, len, 0, ai->ai_addr, ai->ai_addrlen);
}
return 0;
}

View file

@ -1,6 +1,6 @@
#!/bin/sh
. ./testlib.sh
. "${0%/*}/testlib.sh"
# Initialize server node

98
test/security.test Executable file
View file

@ -0,0 +1,98 @@
#!/bin/sh
. "${0%/*}/testlib.sh"
# Skip this test if tools are missing
which socket >/dev/null || exit 77
which timeout >/dev/null || exit 77
# Initialize two nodes
$tinc $c1 <<EOF
init foo
set DeviceType dummy
set Port 32754
set Address localhost
set PingTimeout 1
set AutoConnect no
EOF
$tinc $c2 <<EOF
init bar
set DeviceType dummy
set Port 32755
set PingTimeout 1
set MaxTimeout 1
set ExperimentalProtocol no
set AutoConnect no
EOF
# Exchange host config files
$tinc $c1 export | $tinc $c2 exchange | $tinc $c1 import
$tinc $c1 start $r1
$tinc $c2 start $r2
# No ID sent by responding node if we don't send an ID first, before the timeout
result=`(sleep 2; echo "0 bar 17.7") | timeout 3 socket localhost 32754` && exit 1
test $? = 124
test -z "$result"
# ID sent if initiator sends first, but still tarpitted
result=`echo "0 bar 17.7" | timeout 3 socket localhost 32754` && exit 1
test $? = 124
test "`echo "$result" | head -c 10`" = "0 foo 17.7"
# No invalid IDs allowed
result=`echo "0 foo 17.7" | timeout 1 socket localhost 32754` && exit 1
test $? = 124
test -z "$result"
result=`echo "0 baz 17.7" | timeout 1 socket localhost 32754` && exit 1
test $? = 124
test -z "$result"
# No NULL METAKEYs allowed
result=`printf "0 foo 17.0\n1 0 672 0 0 834188619F4D943FD0F4B1336F428BD4AC06171FEABA66BD2356BC9593F0ECD643F0E4B748C670D7750DFDE75DC9F1D8F65AB1026F5ED2A176466FBA4167CC567A2085ABD070C1545B180BDA86020E275EA9335F509C57786F4ED2378EFFF331869B856DDE1C05C461E4EECAF0E2FB97AF77B7BC2AD1B34C12992E45F5D1254BBF0C3FB224ABB3E8859594A83B6CA393ED81ECAC9221CE6BC71A727BCAD87DD80FC0834B87BADB5CB8FD3F08BEF90115A8DF1923D7CD9529729F27E1B8ABD83C4CF8818AE10257162E0057A658E265610B71F9BA4B365A20C70578FAC65B51B91100392171BA12A440A5E93C4AA62E0C9B6FC9B68F953514AAA7831B4B2C31C4\n" | timeout 3 socket localhost 32755` && exit 1
test $? = 124
test -z "$result" # Not even the ID should be sent when the first packet contains illegal data
# No splicing allowed
$tinc $c2 stop
$tinc $c2 del ExperimentalProtocol
$tinc $c2 start $r2
./splice foo localhost 32754 bar localhost 32755 17.7 &
sleep 3
test `$tinc $c1 dump reachable nodes | wc -l` = 1
test `$tinc $c2 dump reachable nodes | wc -l` = 1
kill $!
$tinc $c2 stop
$tinc $c1 stop
# Test splicing again with legacy protocol
$tinc $c1 set ExperimentalProtocol no
$tinc $c2 set ExperimentalProtocol no
$tinc $c1 start $r1
$tinc $c2 start $r2
./splice foo localhost 32754 bar localhost 32755 17.0 &
sleep 3
test `$tinc $c1 dump reachable nodes | wc -l` = 1
test `$tinc $c2 dump reachable nodes | wc -l` = 1
kill $!
# Clean up
$tinc $c2 stop
$tinc $c1 stop

144
test/splice.c Normal file
View file

@ -0,0 +1,144 @@
/*
splice.c -- Splice two outgoing tinc connections together
Copyright (C) 2018 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#ifdef HAVE_MINGW
extern const char *winerror(int);
#define strerror(x) ((x)>0?strerror(x):winerror(GetLastError()))
#define sockerrno WSAGetLastError()
#define sockstrerror(x) winerror(x)
#else
#define sockerrno errno
#define sockstrerror(x) strerror(x)
#endif
int main(int argc, char *argv[]) {
if(argc < 7) {
fprintf(stderr, "Usage: %s name1 host1 port1 name2 host2 port2 [protocol]\n", argv[0]);
return 1;
}
const char *protocol;
if(argc >= 8) {
protocol = argv[7];
} else {
protocol = "17.7";
}
#ifdef HAVE_MINGW
static struct WSAData wsa_state;
if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) {
return 1;
}
#endif
int sock[2];
char buf[1024];
struct addrinfo *ai, hint;
memset(&hint, 0, sizeof(hint));
hint.ai_family = AF_UNSPEC;
hint.ai_socktype = SOCK_STREAM;
hint.ai_protocol = IPPROTO_TCP;
hint.ai_flags = 0;
for (int i = 0; i < 2; i++) {
if(getaddrinfo(argv[2 + 3 * i], argv[3 + 3 * i], &hint, &ai) || !ai) {
fprintf(stderr, "getaddrinfo() failed: %s\n", sockstrerror(sockerrno));
return 1;
}
sock[i] = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if(sock[i] == -1) {
fprintf(stderr, "Could not create socket: %s\n", sockstrerror(sockerrno));
return 1;
}
if(connect(sock[i], ai->ai_addr, ai->ai_addrlen)) {
fprintf(stderr, "Could not connect to %s: %s\n", argv[i + 3 * i], sockstrerror(sockerrno));
return 1;
}
fprintf(stderr, "Connected to %s\n", argv[1 + 3 * i]);
/* Pretend to be the other one */
int len = snprintf(buf, sizeof buf, "0 %s %s\n", argv[4 - 3 * i], protocol);
if (send(sock[i], buf, len, 0) != len) {
fprintf(stderr, "Error sending data to %s: %s\n", argv[1 + 3 * i], sockstrerror(sockerrno));
return 1;
}
/* Ignore the response */
do {
if (recv(sock[i], buf, 1, 0) != 1) {
fprintf(stderr, "Error reading data from %s: %s\n", argv[1 + 3 * i], sockstrerror(sockerrno));
return 1;
}
} while(*buf != '\n');
}
fprintf(stderr, "Splicing...\n");
int nfds = (sock[0] > sock[1] ? sock[0] : sock[1]) + 1;
while(true) {
fd_set fds;
FD_ZERO(&fds);
FD_SET(sock[0], &fds);
FD_SET(sock[1], &fds);
if(select(nfds, &fds, NULL, NULL, NULL) <= 0) {
return 1;
}
for(int i = 0; i < 2; i++ ) {
if(FD_ISSET(sock[i], &fds)) {
ssize_t len = recv(sock[i], buf, sizeof buf, 0);
if(len < 0) {
fprintf(stderr, "Error while reading from %s: %s\n", argv[1 + i * 3], sockstrerror(sockerrno));
return 1;
}
if(len == 0) {
fprintf(stderr, "Connection closed by %s\n", argv[1 + i * 3]);
return 0;
}
if(send(sock[i ^ 1], buf, len, 0) != len) {
fprintf(stderr, "Error while writing to %s: %s\n", argv[4 - i * 3], sockstrerror(sockerrno));
return 1;
}
}
}
}
return 0;
}

View file

@ -1,10 +1,10 @@
#!/bin/sh
. ./testlib.sh
. "${0%/*}/testlib.sh"
# Skip this test if we did not compile sptps_test
test -e $sptps_test || exit 77
test -e $sptps_test -a -e $sptps_keypair || exit 77
# Generate keys
@ -15,18 +15,18 @@ $sptps_keypair $d1/client.priv $d1/client.pub
# Test transfer of a simple file.
(sleep 1; $sptps_test -4 -q $d1/client.priv $d1/server.pub localhost 32750 <../README) &
(sleep 1; $sptps_test -4 -q $d1/client.priv $d1/server.pub localhost 32750 <Makefile) &
$sptps_test -4 $d1/server.priv $d1/client.pub 32750 >$d1/out1
cmp $d1/out1 ../README
cmp $d1/out1 Makefile
$sptps_test -4 -q $d1/server.priv $d1/client.pub 32750 <../NEWS &
$sptps_test -4 -q $d1/server.priv $d1/client.pub 32750 <Makefile &
sleep 1
$sptps_test -4 $d1/client.priv $d1/server.pub localhost 32750 > $d1/out2
cmp $d1/out2 ../NEWS
cmp $d1/out2 Makefile
# Datagram mode
$sptps_test -4 -dq $d1/server.priv $d1/client.pub 32750 <../COPYING &
$sptps_test -4 -dq $d1/server.priv $d1/client.pub 32750 <Makefile &
sleep 1
sleep 1 | $sptps_test -4 -dq $d1/client.priv $d1/server.pub localhost 32750 >$d1/out3
cmp $d1/out3 ../COPYING
cmp $d1/out3 Makefile

View file

@ -1,6 +1,6 @@
#!/bin/sh
. ./testlib.sh
. "${0%/*}/testlib.sh"
# Initialize one node