From 3f0ae998e8ca768106fbcf85d2cd045ac2a3e875 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Mon, 26 Aug 2019 13:44:40 +0200 Subject: [PATCH] Import Upstream version 1.0.13 --- ChangeLog | 178 +++++++++++++++++++++++++++++++++++++++ NEWS | 12 +++ README | 4 +- THANKS | 1 + config.guess | 149 +++++++++++++------------------- config.h.in | 9 ++ config.sub | 47 ++++++++--- configure | 56 +++++++++--- configure.in | 4 +- doc/sample-config.tar.gz | Bin 1236 -> 1237 bytes doc/tinc.conf.5.in | 39 ++++++++- doc/tinc.info | 149 ++++++++++++++++++++------------ doc/tinc.texi | 42 ++++++++- have.h | 4 + lib/ipv4.h | 4 + lib/ipv6.h | 1 + m4/lzo.m4 | 71 ++++++++-------- m4/zlib.m4 | 53 ++++++------ src/conf.c | 116 +++++++------------------ src/conf.h | 2 +- src/connection.c | 4 +- src/net.c | 39 ++++++++- src/net.h | 1 + src/net_packet.c | 36 +++++++- src/net_setup.c | 95 ++++++++++++++++++++- src/netutl.c | 6 +- src/protocol.c | 1 + src/protocol.h | 1 + src/protocol_auth.c | 5 +- src/protocol_subnet.c | 43 +++++----- src/route.c | 50 +++++++++-- src/route.h | 8 ++ src/subnet.h | 2 + src/tincd.c | 4 + 34 files changed, 861 insertions(+), 375 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7487d17..f2a5307 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,181 @@ +commit 26b8cf8680ae68443dccac2adbc2361caafc3712 +Author: Guus Sliepen +Date: Sun Apr 11 20:40:20 2010 +0200 + + Releasing 1.0.13. + +commit 74653beb5bc510e60579058ee15c0f66350f5137 +Author: Guus Sliepen +Date: Sun Apr 11 19:47:44 2010 +0200 + + Mark Forwarding and DirectOnly options as being experimental. + +commit 0ddce6370d39eff162bd212a6e47fe3a8e96a09e +Author: Guus Sliepen +Date: Sun Apr 11 19:39:31 2010 +0200 + + Don't redefine MAX if it already exists. + +commit a9bbb3357a89e27185312fbce0ee134eda4eda90 +Author: Guus Sliepen +Date: Sun Apr 11 19:20:02 2010 +0200 + + Fixes for definitions under Windows. + +commit 4708f2c89edea4be2562256544cf35309cf1ea89 +Author: Guus Sliepen +Date: Sun Apr 11 18:34:50 2010 +0200 + + Ensure subnet-up/down scripts are called after HUP when necessary. + +commit 32f5524c4b52a2d3a96bc48ee2437f8b9b4dbe10 +Author: Guus Sliepen +Date: Sun Apr 11 04:35:16 2010 +0200 + + Fix reloading Subnets when StrictSubnets is set. + +commit 9f53ab209d8a6a7622a49ed03cef735b6e3f3eeb +Author: Guus Sliepen +Date: Sun Apr 11 00:50:42 2010 +0200 + + Reload Subnets when getting a HUP signal and StrictSubnets is used. + +commit d1cc637470edaed663e694fdeb290eb45cc9ecca +Author: Guus Sliepen +Date: Sat Apr 10 23:55:15 2010 +0200 + + Ensure ICMP_NET_ANO is defined. + +commit f75e71bc693847af71f61fb72cd788e3e47f9bd3 +Author: Guus Sliepen +Date: Sat Apr 3 09:46:45 2010 +0100 + + Convert Port to numeric form before sending it to other nodes. + + If one uses a symbolic name for the Port option, tinc will send that name + literally to other nodes. However, it is not guaranteed that all nodes have + the same contents in /etc/services, or have such a file at all. + +commit 292354912f346fe467f557f0dc026b519997289c +Author: Sven-Haegar Koch +Date: Wed Mar 10 02:50:51 2010 +0100 + + Never delete Subnets when StrictSubnets is set + + If a node is unreachable, and not connected to an edge anymore, it gets + deleted. When this happens its subnets are also removed, which should + not happen with StrictSubnets=yes. + + Solution: + - do not remove subnets in src/net.c::purge(), we know that all subnets + in the list came from our hosts files. + I think here you got the check wrong by looking at the tunnelserver + code below it - with strictsubnets we still inform others but do not + remove the subnet from our data. + - do not remove nodes in net.c::purge() that still have subnets + attached. + +commit 146760bd35b351d58e817ce0e67f5c6f74750cd4 +Author: Guus Sliepen +Date: Wed Mar 10 16:07:01 2010 +0100 + + Fix typo. + +commit f2346771cf5b22092dd3f5af3674008aa1e878d1 +Author: Guus Sliepen +Date: Mon Mar 8 21:44:32 2010 +0100 + + Log unauthorized Subnets when StrictSubnets is set. + +commit ee64b8ef33b709fabfc1ed56762d5f52fc026e52 +Author: Guus Sliepen +Date: Mon Mar 8 17:54:57 2010 +0100 + + ConnectTo does not mean tinc does not listen for incoming connections anymore. + +commit 8ae54dc7c782bcc4b771ec0766fcf9eee115756e +Author: Guus Sliepen +Date: Tue Mar 2 23:27:50 2010 +0100 + + Fixes for the Forwarding option. + +commit 3e4829e78a3c7f7e19017d05611e5b69d5268119 +Author: Guus Sliepen +Date: Tue Mar 2 22:55:24 2010 +0100 + + Add the DirectOnly option. + + When this option is enabled, packets that cannot be sent directly to the destination node, + but which would have to be forwarded by an intermediate node, are dropped instead. + When combined with the IndirectData option, + packets for nodes for which we do not have a meta connection with are also dropped. + +commit 95a6974de173e0cb78611c6704ed09631d510dae +Author: Guus Sliepen +Date: Tue Mar 2 22:34:26 2010 +0100 + + Add the Forwarding option. + + This determines if and how incoming packets that are not meant for the local + node are forwarded. It can either be off, internal (tinc forwards them itself, + as in previous versions), or kernel (packets are always sent to the TUN/TAP + device, letting the kernel sort them out). + +commit 5038964032ef55913b2d4741c67bf191b2208abb +Author: Guus Sliepen +Date: Tue Mar 2 00:18:44 2010 +0100 + + Add the StrictSubnets option. + + When this option is enabled, tinc will not accept dynamic updates of Subnets + from other nodes, but will only use Subnets read from local host config files + to build its routing table. + +commit 9fed0ec34b9208611a7e96a595f23fa04e60a5c0 +Author: Guus Sliepen +Date: Mon Mar 1 23:44:56 2010 +0100 + + Preload all Subnets in TunnelServer mode. + + This simplifies the logic in protocol_subnet.c. + +commit d47ab576a25d91600acf7eecf376ed026bdc9c83 +Author: Guus Sliepen +Date: Mon Mar 1 23:44:46 2010 +0100 + + Check for dirent.h. + +commit 21f33b638291c2ffe7156e6c1e0df339f855d831 +Author: Guus Sliepen +Date: Mon Mar 1 23:35:02 2010 +0100 + + Simplify reading lines from configuration files. + + Instead of allocating storage for each line read, we now read into fixed-size + buffers on the stack. This fixes a case where a malformed configuration file + could crash tinc. + +commit 3cb91d75f874e3398c35cd4280c1e0a1ceeedabc +Author: Guus Sliepen +Date: Sun Feb 28 18:20:13 2010 +0100 + + Clamp MSS to miminum MTU in both directions. + + Clamp MSS of both incoming and outgoing packets, and use the minimum of the + PMTU of both directions when clamping. + +commit ddb8cb0779ed36d17ce186dd0bf67e9f0c860d28 +Author: Timothy Redaelli +Date: Wed Feb 10 14:52:15 2010 +0100 + + Add --disable-zlib configure option + +commit eeb505af36ba9496ad29b32cd0917afb8c6cd355 +Author: Timothy Redaelli +Date: Wed Feb 10 13:24:33 2010 +0100 + + Add --disable-lzo configure option + commit f7b2a2ea43fca323f543e152e6a43a29a4eb6671 Author: Guus Sliepen Date: Wed Feb 3 22:49:48 2010 +0100 diff --git a/NEWS b/NEWS index 942398e..a753f1c 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,15 @@ +Version 1.0.13 Apr 11 2010 + + * Allow building tinc without LZO and/or Zlib. + + * Clamp MSS of TCP packets in both directions. + + * Experimental StrictSubnets, Forwarding and DirectOnly options, + giving more control over information and packets received from/sent to other + nodes. + + * Ensure tinc never sends symbolic names for ports over the wire. + Version 1.0.12 Feb 3 2010 * Really allow fast roaming of hosts to other nodes in a switched VPN. diff --git a/README b/README index 9cc1042..80cf0a6 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -This is the README file for tinc version 1.0.12. Installation +This is the README file for tinc version 1.0.13. Installation instructions may be found in the INSTALL file. tinc is Copyright (C) 1998-2010 by: @@ -55,7 +55,7 @@ should be changed into "Device", and "Device" should be changed into Compatibility ------------- -Version 1.0.12 is compatible with 1.0pre8, 1.0 and later, but not with older +Version 1.0.13 is compatible with 1.0pre8, 1.0 and later, but not with older versions of tinc. diff --git a/THANKS b/THANKS index e0d33d3..08f17d5 100644 --- a/THANKS +++ b/THANKS @@ -34,6 +34,7 @@ We would like to thank the following people for their contributions to tinc: * Scott Lamb * Sven-Haegar Koch * Teemu Kiviniemi +* Timothy Redaelli * Tonnerre Lombard * Wessel Dankers * Wouter van Heyst diff --git a/config.guess b/config.guess index e3a2116..c2246a4 100755 --- a/config.guess +++ b/config.guess @@ -1,10 +1,10 @@ #! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 # Free Software Foundation, Inc. -timestamp='2009-06-10' +timestamp='2009-12-30' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -27,16 +27,16 @@ timestamp='2009-06-10' # the same distribution terms that you use for the rest of that program. -# Originally written by Per Bothner . -# Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. +# Originally written by Per Bothner. Please send patches (context +# diff format) to and include a ChangeLog +# entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # -# The plan is that this can be called by configure scripts if you -# don't specify an explicit build system type. +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD me=`echo "$0" | sed -e 's,.*/,,'` @@ -56,8 +56,9 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, -2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free +Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -333,6 +334,9 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" @@ -807,12 +811,12 @@ EOF i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; - *:Interix*:[3456]*) + *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; - EM64T | authenticamd | genuineintel) + authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) @@ -854,6 +858,20 @@ EOF i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ @@ -876,6 +894,17 @@ EOF frv:Linux:*:*) echo frv-unknown-linux-gnu exit ;; + i*86:Linux:*:*) + LIBC=gnu + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; @@ -901,39 +930,18 @@ EOF #endif #endif EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' - /^CPU/{ - s: ::g - p - }'`" + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) echo or32-unknown-linux-gnu exit ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit ;; padre:Linux:*:*) echo sparc-unknown-linux-gnu exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in @@ -942,8 +950,11 @@ EOF *) echo hppa-unknown-linux-gnu ;; esac exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux @@ -966,58 +977,6 @@ EOF xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; - i*86:Linux:*:*) - # The BFD linker knows what the default object file format is, so - # first see if it will tell us. cd to the root directory to prevent - # problems with other programs or directories called `ld' in the path. - # Set LC_ALL=C to ensure ld outputs messages in English. - ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ - | sed -ne '/supported targets:/!d - s/[ ][ ]*/ /g - s/.*supported targets: *// - s/ .*// - p'` - case "$ld_supported_targets" in - elf32-i386) - TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" - ;; - esac - # Determine whether the default compiler is a.out or elf - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - #ifdef __ELF__ - # ifdef __GLIBC__ - # if __GLIBC__ >= 2 - LIBC=gnu - # else - LIBC=gnulibc1 - # endif - # else - LIBC=gnulibc1 - # endif - #else - #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) - LIBC=gnu - #else - LIBC=gnuaout - #endif - #endif - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' - /^LIBC/{ - s: ::g - p - }'`" - test x"${LIBC}" != x && { - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" - exit - } - test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } - ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both @@ -1247,6 +1206,16 @@ EOF *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in + i386) + eval $set_cc_for_build + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + UNAME_PROCESSOR="x86_64" + fi + fi ;; unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} diff --git a/config.h.in b/config.h.in index afd4b5f..3389e9b 100644 --- a/config.h.in +++ b/config.h.in @@ -55,6 +55,9 @@ don't. */ #undef HAVE_DECL_GETNAMEINFO +/* Define to 1 if you have the header file. */ +#undef HAVE_DIRENT_H + /* Define to 1 if you have the `EVP_EncryptInit_ex' function. */ #undef HAVE_EVP_ENCRYPTINIT_EX @@ -94,6 +97,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_IF_TUN_H +/* enable lzo compression support */ +#undef HAVE_LZO + /* Define to 1 if you have the header file. */ #undef HAVE_LZO1X_H @@ -327,6 +333,9 @@ /* Define to 1 if you have the `writev' function. */ #undef HAVE_WRITEV +/* have zlib compression support */ +#undef HAVE_ZLIB + /* Define to 1 if you have the header file. */ #undef HAVE_ZLIB_H diff --git a/config.sub b/config.sub index eb0389a..c2d1257 100755 --- a/config.sub +++ b/config.sub @@ -1,10 +1,10 @@ #! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 # Free Software Foundation, Inc. -timestamp='2009-06-11' +timestamp='2010-01-22' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software @@ -32,13 +32,16 @@ timestamp='2009-06-11' # Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. +# diff and a properly formatted GNU ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. @@ -72,8 +75,9 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, -2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free +Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -149,7 +153,7 @@ case $os in -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis | -knuth | -cray) + -apple | -axis | -knuth | -cray | -microblaze) os= basic_machine=$1 ;; @@ -284,6 +288,7 @@ case $basic_machine in | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ + | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ @@ -291,13 +296,14 @@ case $basic_machine in | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ + | ubicom32 \ | v850 | v850e \ | we32k \ | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; - m6811 | m68hc11 | m6812 | m68hc12) + m6811 | m68hc11 | m6812 | m68hc12 | picochip) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none @@ -340,7 +346,7 @@ case $basic_machine in | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ @@ -368,15 +374,17 @@ case $basic_machine in | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ - | romp-* | rs6000-* \ + | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile-* | tilegx-* \ | tron-* \ + | ubicom32-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ @@ -726,6 +734,9 @@ case $basic_machine in basic_machine=ns32k-utek os=-sysv ;; + microblaze) + basic_machine=microblaze-xilinx + ;; mingw32) basic_machine=i386-pc os=-mingw32 @@ -1076,6 +1087,11 @@ case $basic_machine in basic_machine=tic6x-unknown os=-coff ;; + # This must be matched before tile*. + tilegx*) + basic_machine=tilegx-unknown + os=-linux-gnu + ;; tile*) basic_machine=tile-unknown os=-linux-gnu @@ -1247,6 +1263,9 @@ case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; @@ -1268,8 +1287,8 @@ case $os in # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ - | -kopensolaris* \ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ @@ -1290,7 +1309,7 @@ case $os in | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) @@ -1423,6 +1442,8 @@ case $os in -dicos*) os=-dicos ;; + -nacl*) + ;; -none) ;; *) diff --git a/configure b/configure index aaaa854..e1ce990 100755 --- a/configure +++ b/configure @@ -702,9 +702,11 @@ with_windows2000 with_openssl with_openssl_include with_openssl_lib +enable_zlib with_zlib with_zlib_include with_zlib_lib +enable_lzo with_lzo with_lzo_include with_lzo_lib @@ -1341,6 +1343,8 @@ Optional Features: --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors --enable-tunemu enable support for the tunemu driver + --disable-zlib disable zlib compression support + --disable-lzo disable lzo compression support --enable-jumbograms enable support for jumbograms (packets up to 9000 bytes) @@ -2704,7 +2708,7 @@ fi # Define the identity of the package. PACKAGE=tinc - VERSION=1.0.12 + VERSION=1.0.13 cat >>confdefs.h <<_ACEOF @@ -5001,7 +5005,7 @@ $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi -for ac_header in stdbool.h syslog.h sys/file.h sys/ioctl.h sys/mman.h sys/param.h sys/socket.h sys/time.h sys/uio.h sys/wait.h netdb.h arpa/inet.h +for ac_header in stdbool.h syslog.h sys/file.h sys/ioctl.h sys/mman.h sys/param.h sys/socket.h sys/time.h sys/uio.h sys/wait.h netdb.h arpa/inet.h dirent.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" @@ -6347,12 +6351,22 @@ fi + # Check whether --enable-zlib was given. +if test "${enable_zlib+set}" = set; then : + enableval=$enable_zlib; +fi + + if test "x$enable_zlib" != "xno"; then : + + +$as_echo "#define HAVE_ZLIB 1" >>confdefs.h + # Check whether --with-zlib was given. if test "${with_zlib+set}" = set; then : withval=$with_zlib; zlib="$withval" - CPPFLAGS="$CPPFLAGS -I$withval/include" - LDFLAGS="$LDFLAGS -L$withval/lib" + CPPFLAGS="$CPPFLAGS -I$withval/include" + LDFLAGS="$LDFLAGS -L$withval/lib" fi @@ -6361,7 +6375,7 @@ fi # Check whether --with-zlib-include was given. if test "${with_zlib_include+set}" = set; then : withval=$with_zlib_include; zlib_include="$withval" - CPPFLAGS="$CPPFLAGS -I$withval" + CPPFLAGS="$CPPFLAGS -I$withval" fi @@ -6370,12 +6384,12 @@ fi # Check whether --with-zlib-lib was given. if test "${with_zlib_lib+set}" = set; then : withval=$with_zlib_lib; zlib_lib="$withval" - LDFLAGS="$LDFLAGS -L$withval" + LDFLAGS="$LDFLAGS -L$withval" fi - for ac_header in zlib.h + for ac_header in zlib.h do : ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" if test "x$ac_cv_header_zlib_h" = x""yes; then : @@ -6391,7 +6405,7 @@ fi done - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for compress2 in -lz" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for compress2 in -lz" >&5 $as_echo_n "checking for compress2 in -lz... " >&6; } if test "${ac_cv_lib_z_compress2+set}" = set; then : $as_echo_n "(cached) " >&6 @@ -6435,13 +6449,25 @@ else fi +fi + + + # Check whether --enable-lzo was given. +if test "${enable_lzo+set}" = set; then : + enableval=$enable_lzo; +fi + + if test "x$enable_lzo" != "xno"; then : + + +$as_echo "#define HAVE_LZO 1" >>confdefs.h # Check whether --with-lzo was given. if test "${with_lzo+set}" = set; then : withval=$with_lzo; lzo="$withval" - CPPFLAGS="$CPPFLAGS -I$withval/include" - LDFLAGS="$LDFLAGS -L$withval/lib" + CPPFLAGS="$CPPFLAGS -I$withval/include" + LDFLAGS="$LDFLAGS -L$withval/lib" fi @@ -6450,7 +6476,7 @@ fi # Check whether --with-lzo-include was given. if test "${with_lzo_include+set}" = set; then : withval=$with_lzo_include; lzo_include="$withval" - CPPFLAGS="$CPPFLAGS -I$withval" + CPPFLAGS="$CPPFLAGS -I$withval" fi @@ -6459,12 +6485,12 @@ fi # Check whether --with-lzo-lib was given. if test "${with_lzo_lib+set}" = set; then : withval=$with_lzo_lib; lzo_lib="$withval" - LDFLAGS="$LDFLAGS -L$withval" + LDFLAGS="$LDFLAGS -L$withval" fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lzo1x_1_compress in -llzo2" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lzo1x_1_compress in -llzo2" >&5 $as_echo_n "checking for lzo1x_1_compress in -llzo2... " >&6; } if test "${ac_cv_lib_lzo2_lzo1x_1_compress+set}" = set; then : $as_echo_n "(cached) " >&6 @@ -6550,7 +6576,7 @@ fi fi - for ac_header in lzo/lzo1x.h + for ac_header in lzo/lzo1x.h do : ac_fn_c_check_header_mongrel "$LINENO" "lzo/lzo1x.h" "ac_cv_header_lzo_lzo1x_h" "$ac_includes_default" if test "x$ac_cv_header_lzo_lzo1x_h" = x""yes; then : @@ -6600,6 +6626,8 @@ fi done +fi + # Check whether --enable-jumbograms was given. if test "${enable_jumbograms+set}" = set; then : diff --git a/configure.in b/configure.in index df15067..9a2b88d 100644 --- a/configure.in +++ b/configure.in @@ -3,7 +3,7 @@ dnl Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) AC_INIT AC_CONFIG_SRCDIR([src/tincd.c]) -AM_INIT_AUTOMAKE(tinc, 1.0.12) +AM_INIT_AUTOMAKE(tinc, 1.0.13) AC_CONFIG_HEADERS([config.h]) AM_MAINTAINER_MODE @@ -99,7 +99,7 @@ dnl Checks for header files. dnl We do this in multiple stages, because unlike Linux all the other operating systems really suck and don't include their own dependencies. AC_HEADER_STDC -AC_CHECK_HEADERS([stdbool.h syslog.h sys/file.h sys/ioctl.h sys/mman.h sys/param.h sys/socket.h sys/time.h sys/uio.h sys/wait.h netdb.h arpa/inet.h]) +AC_CHECK_HEADERS([stdbool.h syslog.h sys/file.h sys/ioctl.h sys/mman.h sys/param.h sys/socket.h sys/time.h sys/uio.h sys/wait.h netdb.h arpa/inet.h dirent.h]) AC_CHECK_HEADERS([net/if.h net/if_types.h linux/if_tun.h net/if_tun.h net/if_tap.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h], [], [], [#include "have.h"] ) diff --git a/doc/sample-config.tar.gz b/doc/sample-config.tar.gz index da56735ee90b456f03edcfc9b73a0c4ebb73e4d4..6202664043149dc2803cc4ba3d207ff5be8b0fda 100644 GIT binary patch literal 1237 zcmV;`1S9%M5X+Jr*=>P*$Xf%WT^1zifPPwO ziMEMIq()Ls{qK86%8l)~^NQKt0_c!HvU#s0@3}i0R+Kq!r%H~*xO1=*3X%F@NYALB zEIsFR5Jgek>&M-0H#rESFzFv3K(ZTmc0=<(=Fb;GX6gJV%2>1YTk!MeAN9M<`R|3+ zo&S(qwoMzfAHBah|9%{=oPV4|$pLKBhn>?4J^w?vb2k9!=)qruN;4~zgptU3>k#fI z!nk*MWCq4ua$M&b3};@5u1nBzj2tv)ISg)qWtry2fEs}%c`Ib<*aJ9c5@nz=UWc+1 zuAkOT&^oPUPaulB!EqAw`a$&OEt$Ac+RCaJqQppPKp|BKIVQ&?PswW&zy%+%Dz|`U zdr1HUVH${`Zn-HUE44u*v^@ z(8m1VSzgE8U)5LHCxWl@!cNxS>My&xh7J8kw4DER{J)y9VWk76A5SL%N^?lt+p5BgsJ zU7`L_{YPNHKZff?!6jBo6f0TE@jID;WkYXLZ^MvNs2%hwjmp%$sl zXIP9;)G$3m@fnt4Ip+EZ@kdqT3CvUl1)JfpAuVdL3Ubb-90b;F2{?h!OHpbyMf2E} zWNavMVQ28}S7iT#X~BjVk7Nb+URh+KN}V!;TBPC92rH)i`^-YD>l&I{{#PY51#?Xt zC*T_6xs;HWYibu<=Y($7y^2FmivQei7PTX2SXGXxU=N%^)Q0CH+|gVZ%Vk?h+?Jd#?g}B;k*gwt#vZ45E@5lPLy$?ycM_42VXz zc|4YtknyQV>$~tM@|+Zs`i0J`gFGGN4V_|6u8<_Yzt^0f-CZ0Zzh|nXXS!24o{GOK zzn5IrO!Uz);wBQaaOwS>kVM(H7`A{5 z|9IeX5ZxRaz5JIz;m$*rJ(tH6U?`L!6QhL#K0C|7CD}e|h`<^!(BdSlods$!js5 zc$FxQ#j7AxE^}tlKw*wxi1;f;R6H`pT{-geAQmCiK#FjwU=oMMeCA5SmGD*PNxLW= zXd(U-%sfzmC^*fmM~=tT11J>|a$*5c9grhFBMy!Ux+hHfNz^lAEy=`GWHhk)8PpIy z8WbN1iI6V*Q2T=!{Z&hh{I`qS^EAUobB`g$v6=qEAgs}IP5x)Bdfxwa z`%V7ugVyJNnk$1jPB-Bh2CTho#M#v2h8k+9p@tf2sG)`$`k&J`n4CJa04M+eD{g56 literal 1236 zcmV;_1S|U=iwFQ_>}g8?1MOICZ`(Kw?&tgp4n1HvpmFTHc^l9VecKRh*DIRtfPK2j zwvq_7C7&cG%fBBfIcwTx7Yvu=P{2eBI}u5dlAecD3@gf?VaTNxb7nc<&_d~Z z9AnNwu2LMOxm+49gI4VV<9pi;qT!n$3c^mezgmN`N^+6HJzv6B9A9uS?@jvK>4gL=yTk*f%7A}~1eDa+U9hYE#JkckP2%YpysJ^fC1O*_f}@u?(}E=! z+1j0xaDyPkiOF7z>CC%CbHsK*)Kuoo;sk{`fuuq>PcRY;lN2{^f1vXV(20r(tj9)HBUUpe?ad$ zJ!4z&A9dsBzyCD&KaBjS|E>W4tp7)-;UB~Cg5XGC9+xad8X!Damf(v<#O4C4F;%;u z#_%Z^F_macfHPK$)aFY(j%aEaLJ#=@E3BM)45?~5bIeh&rDG35k%F8vk3@t4f`VR( zQY&I1Y&SBNh+Nnuy!##1|5_0RF@cZDq7oJ0lo>*r;nE0;*#6P8I3C*2sNC{@DxoQv zYtlFccQIaB32C_|z&li8m~{{07?1M5@QX#r#feqrlnQpwDMf8~KEV~ug|S?=mBeLv zXkyU%3oQfDMpd)sDoQ4wbWAkYAGlzvo~pp!NBAwJB_M*uBr2IPNgRIRXSq|D5VdZr zeAej7xn77oCx_&It)uFoP6u^E=a^F{WQp(Zu@an*FHcb4D^=1fjTQ2q@Mq=ElFM3& zJ~~BQL{fITpMh{_ll@ ye#8HV5Nvbm8;Yktf6t?yZPR7tYlFE)8fm1FMjC0PkwzMM!SWr<^^cVRC;$McoLKe% diff --git a/doc/tinc.conf.5.in b/doc/tinc.conf.5.in index e6b3553..bc82b17 100644 --- a/doc/tinc.conf.5.in +++ b/doc/tinc.conf.5.in @@ -199,6 +199,32 @@ Tinc will expect packets read from the virtual network device to start with an Ethernet header. .El +.It Va DirectOnly Li = yes | no Po no Pc Bq experimental +When this option is enabled, packets that cannot be sent directly to the destination node, +but which would have to be forwarded by an intermediate node, are dropped instead. +When combined with the IndirectData option, +packets for nodes for which we do not have a meta connection with are also dropped. + +.It Va Forwarding Li = off | internal | kernel Po internal Pc Bq experimental +This option selects the way indirect packets are forwarded. +.Bl -tag -width indent + +.It off +Incoming packets that are not meant for the local node, +but which should be forwarded to another node, are dropped. + +.It internal +Incoming packets that are meant for another node are forwarded by tinc internally. + +.Pp +This is the default mode, and unless you really know you need another forwarding mode, don't change it. + +.It kernel +Incoming packets are always sent to the TUN/TAP device, even if the packets are not for the local node. +This is less efficient, but allows the kernel to apply its routing and firewall rules on them, +and can also help debugging. +.El + .It Va GraphDumpFile Li = Ar filename Bq experimental If this option is present, .Nm tinc @@ -308,11 +334,18 @@ specified in the configuration file. When this option is used the priority of the tincd process will be adjusted. Increasing the priority may help to reduce latency and packet loss on the VPN. -.It Va TunnelServer Li = yes | no Po no Pc Bq experimental -When this option is enabled tinc will no longer forward information between other tinc daemons, -and will only allow nodes and subnets on the VPN which are present in the +.It Va StrictSubnets Li = yes | no Po no Pc Bq experimental +When this option is enabled tinc will only use Subnet statements which are +present in the host config files in the local .Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ directory. + +.It Va TunnelServer Li = yes | no Po no Pc Bq experimental +When this option is enabled tinc will no longer forward information between other tinc daemons, +and will only allow connections with nodes for which host config files are present in the local +.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ +directory. +Setting this options also implicitly sets StrictSubnets. .El .Sh HOST CONFIGURATION FILES diff --git a/doc/tinc.info b/doc/tinc.info index ff4088f..272a647 100644 --- a/doc/tinc.info +++ b/doc/tinc.info @@ -5,7 +5,7 @@ START-INFO-DIR-ENTRY * tinc: (tinc). The tinc Manual. END-INFO-DIR-ENTRY - This is the info manual for tinc version 1.0.12, a Virtual Private + This is the info manual for tinc version 1.0.13, a Virtual Private Network daemon. Copyright (C) 1998-2010 Ivo Timmermans, Guus Sliepen @@ -738,6 +738,33 @@ DeviceType = (only supported on BSD platforms) Set type to tap. Tinc will expect packets read from the virtual network device to start with an Ethernet header. +DirectOnly = (no) [experimental] + When this option is enabled, packets that cannot be sent directly + to the destination node, but which would have to be forwarded by + an intermediate node, are dropped instead. When combined with the + IndirectData option, packets for nodes for which we do not have a + meta connection with are also dropped. + +Forwarding = (internal) [experimental] + This option selects the way indirect packets are forwarded. + + off + Incoming packets that are not meant for the local node, but + which should be forwarded to another node, are dropped. + + internal + Incoming packets that are meant for another node are + forwarded by tinc internally. + + This is the default mode, and unless you really know you need + another forwarding mode, don't change it. + + kernel + Incoming packets are always sent to the TUN/TAP device, even + if the packets are not for the local node. This is less + efficient, but allows the kernel to apply its routing and + firewall rules on them, and can also help debugging. + GraphDumpFile = [experimental] If this option is present, tinc will dump the current network graph to the file FILENAME every minute, unless there were no @@ -842,11 +869,17 @@ ProcessPriority = adjusted. Increasing the priority may help to reduce latency and packet loss on the VPN. +StrictSubnets (no) [experimental] + When this option is enabled tinc will only use Subnet statements + which are present in the host config files in the local + `/etc/tinc/NETNAME/hosts/' directory. + TunnelServer = (no) [experimental] When this option is enabled tinc will no longer forward - information between other tinc daemons, and will only allow nodes - and subnets on the VPN which are present in the - `/etc/tinc/NETNAME/hosts/' directory. + information between other tinc daemons, and will only allow + connections with nodes for which host config files are present in + the local `/etc/tinc/NETNAME/hosts/' directory. Setting this + options also implicitly sets StrictSubnets.  @@ -1200,9 +1233,9 @@ _BranchA_ would be configured like this: Note that the IP addresses of eth0 and tap0 are the same. This is quite possible, if you make sure that the netmasks of the interfaces -are different. It is in fact recommended to give give both real -internal network interfaces and tap interfaces the same IP address, -since that will make things a lot easier to remember and set up. +are different. It is in fact recommended to give both real internal +network interfaces and tap interfaces the same IP address, since that +will make things a lot easier to remember and set up. For Branch B ............ @@ -1220,8 +1253,8 @@ In `/etc/tinc/company/tinc-up': ConnectTo = BranchA Note here that the internal address (on eth0) doesn't have to be the -same as on the tap0 device. Also, ConnectTo is given so that no-one can -connect to this node. +same as on the tap0 device. Also, ConnectTo is given so that this node +will always try to connect to BranchA. On all hosts, in `/etc/tinc/company/hosts/BranchB': @@ -2258,47 +2291,51 @@ Concept Index (line 45) * Digest: Host configuration variables. (line 29) +* DirectOnly: Main configuration variables. + (line 73) * encapsulating: The UDP tunnel. (line 30) * encryption: Encryption of network packets. (line 6) * environment variables: Scripts. (line 43) * example: Example configuration. (line 6) +* Forwarding: Main configuration variables. + (line 80) * frame type: The UDP tunnel. (line 6) * GraphDumpFile: Main configuration variables. - (line 73) + (line 100) * Hostnames: Main configuration variables. - (line 81) + (line 108) * hub: Main configuration variables. - (line 122) + (line 149) * ID: Authentication protocol. (line 10) * IndirectData: Host configuration variables. (line 34) * INTERFACE: Scripts. (line 58) * Interface: Main configuration variables. - (line 91) + (line 118) * IRC: Contact information. (line 9) * key generation: Generating keypairs. (line 6) * KEY_CHANGED: The meta-protocol. (line 64) * KeyExpire: Main configuration variables. - (line 127) + (line 154) * libraries: Libraries. (line 6) * license: OpenSSL. (line 36) * lzo: lzo. (line 6) * MACExpire: Main configuration variables. - (line 133) + (line 160) * MACLength: Host configuration variables. (line 42) * meta-protocol: The meta-connection. (line 18) * META_KEY: Authentication protocol. (line 10) * Mode: Main configuration variables. - (line 99) + (line 126) * multiple networks: Multiple networks. (line 6) * NAME: Scripts. (line 52) * Name: Main configuration variables. - (line 138) + (line 165) * netmask: Network interfaces. (line 34) * NETNAME: Scripts. (line 49) * netname: Multiple networks. (line 6) @@ -2311,9 +2348,9 @@ Concept Index (line 67) * PING: The meta-protocol. (line 89) * PingInterval: Main configuration variables. - (line 143) + (line 170) * PingTimeout: Main configuration variables. - (line 147) + (line 174) * platforms: Supported platforms. (line 6) * PMTU: Host configuration variables. (line 47) @@ -2324,15 +2361,15 @@ Concept Index (line 55) * port numbers: Other files. (line 17) * PriorityInheritance: Main configuration variables. - (line 153) + (line 180) * private: Virtual Private Networks. (line 10) * PrivateKey: Main configuration variables. - (line 158) + (line 185) * PrivateKeyFile: Main configuration variables. - (line 164) + (line 191) * ProcessPriority: Main configuration variables. - (line 172) + (line 199) * PublicKey: Host configuration variables. (line 59) * PublicKeyFile: Host configuration variables. @@ -2343,13 +2380,15 @@ Concept Index * REQ_KEY: The meta-protocol. (line 64) * requirements: Libraries. (line 6) * router: Main configuration variables. - (line 102) + (line 129) * runtime options: Runtime options. (line 9) * scalability: tinc. (line 19) * scripts: Scripts. (line 6) * server: How connections work. (line 18) * signals: Signals. (line 6) +* StrictSubnets: Main configuration variables. + (line 204) * SUBNET: Scripts. (line 74) * Subnet: Host configuration variables. (line 74) @@ -2357,7 +2396,7 @@ Concept Index (line 97) * SVPN: Security. (line 11) * switch: Main configuration variables. - (line 111) + (line 138) * TCP: The meta-connection. (line 10) * TCPonly: Host configuration variables. (line 104) @@ -2371,7 +2410,7 @@ Concept Index * tunifhead: Main configuration variables. (line 62) * TunnelServer: Main configuration variables. - (line 177) + (line 209) * tunnohead: Main configuration variables. (line 56) * UDP <1>: Encryption of network packets. @@ -2424,34 +2463,34 @@ Node: Multiple networks21168 Node: How connections work22594 Node: Configuration files23816 Node: Main configuration variables24823 -Node: Host configuration variables32865 -Node: Scripts38276 -Node: How to configure41046 -Node: Generating keypairs42309 -Node: Network interfaces42808 -Node: Example configuration44656 -Node: Running tinc49968 -Node: Runtime options50558 -Node: Signals53353 -Node: Debug levels54422 -Node: Solving problems55358 -Node: Error messages56910 -Node: Sending bug reports60923 -Node: Technical information61875 -Node: The connection62106 -Node: The UDP tunnel62418 -Node: The meta-connection65479 -Node: The meta-protocol66948 -Node: Security71957 -Node: Authentication protocol73087 -Node: Encryption of network packets78091 -Node: Security issues79464 -Node: Platform specific information81081 -Node: Interface configuration81309 -Node: Routes83208 -Node: About us85124 -Node: Contact information85299 -Node: Authors85703 -Node: Concept Index86108 +Node: Host configuration variables34334 +Node: Scripts39745 +Node: How to configure42515 +Node: Generating keypairs43778 +Node: Network interfaces44277 +Node: Example configuration46125 +Node: Running tinc51448 +Node: Runtime options52038 +Node: Signals54833 +Node: Debug levels55902 +Node: Solving problems56838 +Node: Error messages58390 +Node: Sending bug reports62403 +Node: Technical information63355 +Node: The connection63586 +Node: The UDP tunnel63898 +Node: The meta-connection66959 +Node: The meta-protocol68428 +Node: Security73437 +Node: Authentication protocol74567 +Node: Encryption of network packets79571 +Node: Security issues80944 +Node: Platform specific information82561 +Node: Interface configuration82789 +Node: Routes84688 +Node: About us86604 +Node: Contact information86779 +Node: Authors87183 +Node: Concept Index87588  End Tag Table diff --git a/doc/tinc.texi b/doc/tinc.texi index 71babb1..dd7bc62 100644 --- a/doc/tinc.texi +++ b/doc/tinc.texi @@ -818,6 +818,33 @@ Tinc will expect packets read from the virtual network device to start with an Ethernet header. @end table +@cindex DirectOnly +@item DirectOnly = (no) [experimental] +When this option is enabled, packets that cannot be sent directly to the destination node, +but which would have to be forwarded by an intermediate node, are dropped instead. +When combined with the IndirectData option, +packets for nodes for which we do not have a meta connection with are also dropped. + +@cindex Forwarding +@item Forwarding = (internal) [experimental] +This option selects the way indirect packets are forwarded. + +@table @asis +@item off +Incoming packets that are not meant for the local node, +but which should be forwarded to another node, are dropped. + +@item internal +Incoming packets that are meant for another node are forwarded by tinc internally. + +This is the default mode, and unless you really know you need another forwarding mode, don't change it. + +@item kernel +Incoming packets are always sent to the TUN/TAP device, even if the packets are not for the local node. +This is less efficient, but allows the kernel to apply its routing and firewall rules on them, +and can also help debugging. +@end table + @cindex GraphDumpFile @item GraphDumpFile = <@var{filename}> [experimental] If this option is present, @@ -928,11 +955,18 @@ specified in the configuration file. When this option is used the priority of the tincd process will be adjusted. Increasing the priority may help to reduce latency and packet loss on the VPN. +@cindex StrictSubnets +@item StrictSubnets (no) [experimental] +When this option is enabled tinc will only use Subnet statements which are +present in the host config files in the local +@file{@value{sysconfdir}/tinc/@var{netname}/hosts/} directory. + @cindex TunnelServer @item TunnelServer = (no) [experimental] When this option is enabled tinc will no longer forward information between other tinc daemons, -and will only allow nodes and subnets on the VPN which are present in the +and will only allow connections with nodes for which host config files are present in the local @file{@value{sysconfdir}/tinc/@var{netname}/hosts/} directory. +Setting this options also implicitly sets StrictSubnets. @end table @@ -1314,7 +1348,7 @@ Address = 1.2.3.4 Note that the IP addresses of eth0 and tap0 are the same. This is quite possible, if you make sure that the netmasks of the interfaces are different. -It is in fact recommended to give give both real internal network interfaces and tap interfaces the same IP address, +It is in fact recommended to give both real internal network interfaces and tap interfaces the same IP address, since that will make things a lot easier to remember and set up. @@ -1337,8 +1371,8 @@ ConnectTo = BranchA @end example Note here that the internal address (on eth0) doesn't have to be the -same as on the tap0 device. Also, ConnectTo is given so that no-one can -connect to this node. +same as on the tap0 device. Also, ConnectTo is given so that this node will +always try to connect to BranchA. On all hosts, in @file{@value{sysconfdir}/tinc/company/hosts/BranchB}: diff --git a/have.h b/have.h index 9a9efcb..cf5c173 100644 --- a/have.h +++ b/have.h @@ -96,6 +96,10 @@ #include #endif +#ifdef HAVE_DIRENT_H +#include +#endif + /* SunOS really wants sys/socket.h BEFORE net/if.h, and FreeBSD wants these lines below the rest. */ diff --git a/lib/ipv4.h b/lib/ipv4.h index 80ab17c..940c239 100644 --- a/lib/ipv4.h +++ b/lib/ipv4.h @@ -45,6 +45,10 @@ #define ICMP_NET_UNREACH 0 #endif +#ifndef ICMP_NET_ANO +#define ICMP_NET_ANO 9 +#endif + #ifndef IP_MSS #define IP_MSS 576 #endif diff --git a/lib/ipv6.h b/lib/ipv6.h index fee74f5..d98001d 100644 --- a/lib/ipv6.h +++ b/lib/ipv6.h @@ -95,6 +95,7 @@ struct icmp6_hdr { #define ICMP6_DST_UNREACH_NOROUTE 0 #define ICMP6_DST_UNREACH 1 #define ICMP6_PACKET_TOO_BIG 2 +#define ICMP6_DST_UNREACH_ADMIN 1 #define ICMP6_DST_UNREACH_ADDR 3 #define ND_NEIGHBOR_SOLICIT 135 #define ND_NEIGHBOR_ADVERT 136 diff --git a/m4/lzo.m4 b/m4/lzo.m4 index a996b1d..36aa9b7 100644 --- a/m4/lzo.m4 +++ b/m4/lzo.m4 @@ -2,41 +2,46 @@ dnl Check to find the lzo headers/libraries AC_DEFUN([tinc_LZO], [ - AC_ARG_WITH(lzo, - AS_HELP_STRING([--with-lzo=DIR], [lzo base directory, or:]), - [lzo="$withval" - CPPFLAGS="$CPPFLAGS -I$withval/include" - LDFLAGS="$LDFLAGS -L$withval/lib"] - ) + AC_ARG_ENABLE([lzo], + AS_HELP_STRING([--disable-lzo], [disable lzo compression support])) + AS_IF([test "x$enable_lzo" != "xno"], [ + AC_DEFINE(HAVE_LZO, 1, [enable lzo compression support]) + AC_ARG_WITH(lzo, + AS_HELP_STRING([--with-lzo=DIR], [lzo base directory, or:]), + [lzo="$withval" + CPPFLAGS="$CPPFLAGS -I$withval/include" + LDFLAGS="$LDFLAGS -L$withval/lib"] + ) - AC_ARG_WITH(lzo-include, - AS_HELP_STRING([--with-lzo-include=DIR], [lzo headers directory]), - [lzo_include="$withval" - CPPFLAGS="$CPPFLAGS -I$withval"] - ) + AC_ARG_WITH(lzo-include, + AS_HELP_STRING([--with-lzo-include=DIR], [lzo headers directory]), + [lzo_include="$withval" + CPPFLAGS="$CPPFLAGS -I$withval"] + ) - AC_ARG_WITH(lzo-lib, - AS_HELP_STRING([--with-lzo-lib=DIR], [lzo library directory]), - [lzo_lib="$withval" - LDFLAGS="$LDFLAGS -L$withval"] - ) + AC_ARG_WITH(lzo-lib, + AS_HELP_STRING([--with-lzo-lib=DIR], [lzo library directory]), + [lzo_lib="$withval" + LDFLAGS="$LDFLAGS -L$withval"] + ) - AC_CHECK_LIB(lzo2, lzo1x_1_compress, - [LIBS="$LIBS -llzo2"], - [AC_CHECK_LIB(lzo, lzo1x_1_compress, - [LIBS="$LIBS -llzo"], - [AC_MSG_ERROR("lzo libraries not found."); break] - )] - ) - - AC_CHECK_HEADERS(lzo/lzo1x.h, - [AC_DEFINE(LZO1X_H, [], [Location of lzo1x.h])], - [AC_CHECK_HEADERS(lzo2/lzo1x.h, - [AC_DEFINE(LZO1X_H, [], [Location of lzo1x.h])], - [AC_CHECK_HEADERS(lzo1x.h, - [AC_DEFINE(LZO1X_H, [], [Location of lzo1x.h])], - [AC_MSG_ERROR("lzo header files not found."); break] + AC_CHECK_LIB(lzo2, lzo1x_1_compress, + [LIBS="$LIBS -llzo2"], + [AC_CHECK_LIB(lzo, lzo1x_1_compress, + [LIBS="$LIBS -llzo"], + [AC_MSG_ERROR("lzo libraries not found."); break] )] - )] - ) + ) + + AC_CHECK_HEADERS(lzo/lzo1x.h, + [AC_DEFINE(LZO1X_H, [], [Location of lzo1x.h])], + [AC_CHECK_HEADERS(lzo2/lzo1x.h, + [AC_DEFINE(LZO1X_H, [], [Location of lzo1x.h])], + [AC_CHECK_HEADERS(lzo1x.h, + [AC_DEFINE(LZO1X_H, [], [Location of lzo1x.h])], + [AC_MSG_ERROR("lzo header files not found."); break] + )] + )] + ) + ]) ]) diff --git a/m4/zlib.m4 b/m4/zlib.m4 index 71f39f7..64245a5 100644 --- a/m4/zlib.m4 +++ b/m4/zlib.m4 @@ -2,32 +2,37 @@ dnl Check to find the zlib headers/libraries AC_DEFUN([tinc_ZLIB], [ - AC_ARG_WITH(zlib, - AS_HELP_STRING([--with-zlib=DIR], [zlib base directory, or:]), - [zlib="$withval" - CPPFLAGS="$CPPFLAGS -I$withval/include" - LDFLAGS="$LDFLAGS -L$withval/lib"] - ) + AC_ARG_ENABLE([zlib], + AS_HELP_STRING([--disable-zlib], [disable zlib compression support])) + AS_IF([test "x$enable_zlib" != "xno"], [ + AC_DEFINE(HAVE_ZLIB, 1, [have zlib compression support]) + AC_ARG_WITH(zlib, + AS_HELP_STRING([--with-zlib=DIR], [zlib base directory, or:]), + [zlib="$withval" + CPPFLAGS="$CPPFLAGS -I$withval/include" + LDFLAGS="$LDFLAGS -L$withval/lib"] + ) - AC_ARG_WITH(zlib-include, - AS_HELP_STRING([--with-zlib-include=DIR], [zlib headers directory]), - [zlib_include="$withval" - CPPFLAGS="$CPPFLAGS -I$withval"] - ) + AC_ARG_WITH(zlib-include, + AS_HELP_STRING([--with-zlib-include=DIR], [zlib headers directory]), + [zlib_include="$withval" + CPPFLAGS="$CPPFLAGS -I$withval"] + ) - AC_ARG_WITH(zlib-lib, - AS_HELP_STRING([--with-zlib-lib=DIR], [zlib library directory]), - [zlib_lib="$withval" - LDFLAGS="$LDFLAGS -L$withval"] - ) + AC_ARG_WITH(zlib-lib, + AS_HELP_STRING([--with-zlib-lib=DIR], [zlib library directory]), + [zlib_lib="$withval" + LDFLAGS="$LDFLAGS -L$withval"] + ) - AC_CHECK_HEADERS(zlib.h, - [], - [AC_MSG_ERROR("zlib header files not found."); break] - ) + AC_CHECK_HEADERS(zlib.h, + [], + [AC_MSG_ERROR("zlib header files not found."); break] + ) - AC_CHECK_LIB(z, compress2, - [LIBS="$LIBS -lz"], - [AC_MSG_ERROR("zlib libraries not found.")] - ) + AC_CHECK_LIB(z, compress2, + [LIBS="$LIBS -lz"], + [AC_MSG_ERROR("zlib libraries not found.")] + ) + ]) ]) diff --git a/src/conf.c b/src/conf.c index e67c7ac..f64fb22 100644 --- a/src/conf.c +++ b/src/conf.c @@ -26,6 +26,7 @@ #include "conf.h" #include "logger.h" #include "netutl.h" /* for str2address */ +#include "protocol.h" #include "utils.h" /* for cp */ #include "xalloc.h" @@ -206,111 +207,60 @@ bool get_config_subnet(const config_t *cfg, subnet_t ** result) { } /* - Read exactly one line and strip the trailing newline if any. If the - file was on EOF, return NULL. Otherwise, return all the data in a - dynamically allocated buffer. - - If line is non-NULL, it will be used as an initial buffer, to avoid - unnecessary mallocing each time this function is called. If buf is - given, and buf needs to be expanded, the var pointed to by buflen - will be increased. + Read exactly one line and strip the trailing newline if any. */ -static char *readline(FILE * fp, char **buf, size_t *buflen) { +static char *readline(FILE * fp, char *buf, size_t buflen) { char *newline = NULL; char *p; - char *line; /* The array that contains everything that has been read so far */ - char *idx; /* Read into this pointer, which points to an offset within line */ - size_t size, newsize; /* The size of the current array pointed to by line */ - size_t maxlen; /* Maximum number of characters that may be read with fgets. This is newsize - oldsize. */ if(feof(fp)) return NULL; - if(buf && buflen) { - size = *buflen; - line = *buf; - } else { - size = 100; - line = xmalloc(size); - } + p = fgets(buf, buflen, fp); - maxlen = size; - idx = line; - *idx = 0; + if(!p) + return NULL; - for(;;) { - errno = 0; - p = fgets(idx, maxlen, fp); + newline = strchr(p, '\n'); - if(!p) { /* EOF or error */ - if(feof(fp)) - break; + if(!newline) + return NULL; - /* otherwise: error; let the calling function print an error message if applicable */ - free(line); - return NULL; - } + *newline = '\0'; /* kill newline */ + if(newline > p && newline[-1] == '\r') /* and carriage return if necessary */ + newline[-1] = '\0'; - newline = strchr(p, '\n'); - - if(!newline) { /* We haven't yet read everything to the end of the line */ - newsize = size << 1; - line = xrealloc(line, newsize); - idx = &line[size - 1]; - maxlen = newsize - size + 1; - size = newsize; - } else { - *newline = '\0'; /* kill newline */ - if(newline > p && newline[-1] == '\r') /* and carriage return if necessary */ - newline[-1] = '\0'; - break; /* yay */ - } - } - - if(buf && buflen) { - *buflen = size; - *buf = line; - } - - return line; + return buf; } /* Parse a configuration file and put the results in the configuration tree starting at *base. */ -int read_config_file(avl_tree_t *config_tree, const char *fname) { - int err = -2; /* Parse error */ +bool read_config_file(avl_tree_t *config_tree, const char *fname) { FILE *fp; - char *buffer, *line; + char buffer[MAX_STRING_SIZE]; + char *line; char *variable, *value, *eol; int lineno = 0; int len; bool ignore = false; config_t *cfg; - size_t bufsize; + bool result = false; fp = fopen(fname, "r"); if(!fp) { - logger(LOG_ERR, "Cannot open config file %s: %s", fname, - strerror(errno)); - return -3; + logger(LOG_ERR, "Cannot open config file %s: %s", fname, strerror(errno)); + return false; } - bufsize = 100; - buffer = xmalloc(bufsize); - for(;;) { - if(feof(fp)) { - err = 0; - break; - } - - line = readline(fp, &buffer, &bufsize); + line = readline(fp, buffer, sizeof buffer); if(!line) { - err = -1; + if(feof(fp)) + result = true; break; } @@ -361,46 +311,46 @@ int read_config_file(avl_tree_t *config_tree, const char *fname) { config_add(config_tree, cfg); } - free(buffer); fclose(fp); - return err; + return result; } bool read_server_config() { char *fname; - int x; + bool x; xasprintf(&fname, "%s/tinc.conf", confbase); x = read_config_file(config_tree, fname); - if(x == -1) { /* System error: complain */ + if(!x) { /* System error: complain */ logger(LOG_ERR, "Failed to read `%s': %s", fname, strerror(errno)); } free(fname); - return x == 0; + return x; } FILE *ask_and_open(const char *filename, const char *what) { FILE *r; char *directory; - char *fn; + char line[PATH_MAX]; + const char *fn; /* Check stdin and stdout */ if(!isatty(0) || !isatty(1)) { /* Argh, they are running us from a script or something. Write the files to the current directory and let them burn in hell for ever. */ - fn = xstrdup(filename); + fn = filename; } else { /* Ask for a file and/or directory name. */ fprintf(stdout, "Please enter a file to save %s to [%s]: ", what, filename); fflush(stdout); - fn = readline(stdin, NULL, NULL); + fn = readline(stdin, line, sizeof line); if(!fn) { fprintf(stderr, "Error while reading stdin: %s\n", @@ -410,7 +360,7 @@ FILE *ask_and_open(const char *filename, const char *what) { if(!strlen(fn)) /* User just pressed enter. */ - fn = xstrdup(filename); + fn = filename; } #ifdef HAVE_MINGW @@ -423,7 +373,6 @@ FILE *ask_and_open(const char *filename, const char *what) { directory = get_current_dir_name(); xasprintf(&p, "%s/%s", directory, fn); - free(fn); free(directory); fn = p; } @@ -437,12 +386,9 @@ FILE *ask_and_open(const char *filename, const char *what) { if(!r) { fprintf(stderr, "Error opening file `%s': %s\n", fn, strerror(errno)); - free(fn); return NULL; } - free(fn); - return r; } diff --git a/src/conf.h b/src/conf.h index be49733..dae4eab 100644 --- a/src/conf.h +++ b/src/conf.h @@ -54,7 +54,7 @@ extern bool get_config_string(const config_t *, char **); extern bool get_config_address(const config_t *, struct addrinfo **); extern bool get_config_subnet(const config_t *, struct subnet_t **); -extern int read_config_file(avl_tree_t *, const char *); +extern bool read_config_file(avl_tree_t *, const char *); extern bool read_server_config(void); extern FILE *ask_and_open(const char *, const char *); extern bool is_safe_path(const char *); diff --git a/src/connection.c b/src/connection.c index 9a26ec9..6229e79 100644 --- a/src/connection.c +++ b/src/connection.c @@ -130,11 +130,11 @@ void dump_connections(void) { bool read_connection_config(connection_t *c) { char *fname; - int x; + bool x; xasprintf(&fname, "%s/hosts/%s", confbase, c->name); x = read_config_file(c->config_tree, fname); free(fname); - return x == 0; + return x; } diff --git a/src/net.c b/src/net.c index feec8d6..a04ba00 100644 --- a/src/net.c +++ b/src/net.c @@ -68,9 +68,9 @@ static void purge(void) { for(snode = n->subnet_tree->head; snode; snode = snext) { snext = snode->next; s = snode->data; - if(!tunnelserver) - send_del_subnet(broadcast, s); - subnet_del(n, s); + send_del_subnet(broadcast, s); + if(!strictsubnets) + subnet_del(n, s); } for(enode = n->edge_tree->head; enode; enode = enext) { @@ -98,7 +98,8 @@ static void purge(void) { break; } - if(!enode) + if(!enode && (!strictsubnets || !n->subnet_tree->head)) + /* in strictsubnets mode do not delete nodes with subnets */ node_del(n); } } @@ -488,6 +489,36 @@ int main_loop(void) { last_config_check = now; + /* If StrictSubnet is set, expire deleted Subnets and read new ones in */ + + if(strictsubnets) { + subnet_t *subnet; + + for(node = subnet_tree->head; node; node = node->next) { + subnet = node->data; + subnet->expires = 1; + } + + load_all_subnets(); + + for(node = subnet_tree->head; node; node = next) { + next = node->next; + subnet = node->data; + if(subnet->expires == 1) { + send_del_subnet(broadcast, subnet); + if(subnet->owner->status.reachable) + subnet_update(subnet->owner, subnet, false); + subnet_del(subnet->owner, subnet); + } else if(subnet->expires == -1) { + subnet->expires = 0; + } else { + send_add_subnet(broadcast, subnet); + if(subnet->owner->status.reachable) + subnet_update(subnet->owner, subnet, true); + } + } + } + /* Try to make outgoing connections */ try_outgoing_connections(); diff --git a/src/net.h b/src/net.h index fe4b54b..a97759f 100644 --- a/src/net.h +++ b/src/net.h @@ -139,6 +139,7 @@ extern void terminate_connection(struct connection_t *, bool); extern void flush_queue(struct node_t *); extern bool read_rsa_public_key(struct connection_t *); extern void send_mtu_probe(struct node_t *); +extern void load_all_subnets(); #ifndef HAVE_MINGW #define closesocket(s) close(s) diff --git a/src/net_packet.c b/src/net_packet.c index 1f62f64..a438d3e 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -26,8 +26,13 @@ #include #include +#ifdef HAVE_ZLIB #include +#endif + +#ifdef HAVE_LZO #include LZO1X_H +#endif #include "avl_tree.h" #include "conf.h" @@ -48,7 +53,9 @@ int keylifetime = 0; int keyexpires = 0; +#ifdef HAVE_LZO static char lzo_wrkmem[LZO1X_999_MEM_COMPRESS > LZO1X_1_MEM_COMPRESS ? LZO1X_999_MEM_COMPRESS : LZO1X_1_MEM_COMPRESS]; +#endif static void send_udppacket(node_t *, vpn_packet_t *); @@ -147,40 +154,61 @@ void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { } static length_t compress_packet(uint8_t *dest, const uint8_t *source, length_t len, int level) { - if(level == 10) { + if(level == 0) { + memcpy(dest, source, len); + return len; + } else if(level == 10) { +#ifdef HAVE_LZO lzo_uint lzolen = MAXSIZE; lzo1x_1_compress(source, len, dest, &lzolen, lzo_wrkmem); return lzolen; +#else + return -1; +#endif } else if(level < 10) { +#ifdef HAVE_ZLIB unsigned long destlen = MAXSIZE; if(compress2(dest, &destlen, source, len, level) == Z_OK) return destlen; else +#endif return -1; } else { +#ifdef HAVE_LZO lzo_uint lzolen = MAXSIZE; lzo1x_999_compress(source, len, dest, &lzolen, lzo_wrkmem); return lzolen; +#else + return -1; +#endif } return -1; } static length_t uncompress_packet(uint8_t *dest, const uint8_t *source, length_t len, int level) { - if(level > 9) { + if(level == 0) { + memcpy(dest, source, len); + return len; + } else if(level > 9) { +#ifdef HAVE_LZO lzo_uint lzolen = MAXSIZE; if(lzo1x_decompress_safe(source, len, dest, &lzolen, NULL) == LZO_E_OK) return lzolen; else +#endif return -1; - } else { + } +#ifdef HAVE_ZLIB + else { unsigned long destlen = MAXSIZE; if(uncompress(dest, &destlen, source, len) == Z_OK) return destlen; else return -1; } - +#endif + return -1; } diff --git a/src/net_setup.c b/src/net_setup.c index 6360c59..cb70926 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -201,6 +201,68 @@ bool read_rsa_private_key(void) { return true; } +/* + Read Subnets from all host config files +*/ +void load_all_subnets(void) { + DIR *dir; + struct dirent *ent; + char *dname; + char *fname; + avl_tree_t *config_tree; + config_t *cfg; + subnet_t *s, *s2; + node_t *n; + bool result; + + xasprintf(&dname, "%s/hosts", confbase); + dir = opendir(dname); + if(!dir) { + logger(LOG_ERR, "Could not open %s: %s", dname, strerror(errno)); + free(dname); + return; + } + + while((ent = readdir(dir))) { + if(!check_id(ent->d_name)) + continue; + + n = lookup_node(ent->d_name); + #ifdef _DIRENT_HAVE_D_TYPE + //if(ent->d_type != DT_REG) + // continue; + #endif + + xasprintf(&fname, "%s/hosts/%s", confbase, ent->d_name); + init_configuration(&config_tree); + result = read_config_file(config_tree, fname); + free(fname); + if(!result) + continue; + + if(!n) { + n = new_node(); + n->name = xstrdup(ent->d_name); + node_add(n); + } + + for(cfg = lookup_config(config_tree, "Subnet"); cfg; cfg = lookup_config_next(config_tree, cfg)) { + if(!get_config_subnet(cfg, &s)) + continue; + + if((s2 = lookup_subnet(n, s))) { + s2->expires = -1; + } else { + subnet_add(n, s); + } + } + + exit_configuration(&config_tree); + } + + closedir(dir); +} + /* Configure node_t myself and set up the local sockets (listen only) */ @@ -250,6 +312,16 @@ bool setup_myself(void) { && !get_config_string(lookup_config(myself->connection->config_tree, "Port"), &myport)) myport = xstrdup("655"); + if(!atoi(myport)) { + struct addrinfo *ai = str2addrinfo("localhost", myport, SOCK_DGRAM); + sockaddr_t sa; + if(!ai || !ai->ai_addr) + return false; + free(myport); + memcpy(&sa, ai->ai_addr, ai->ai_addrlen); + sockaddr2str(&sa, NULL, &myport); + } + /* Read in all the subnets specified in the host configuration file */ cfg = lookup_config(myself->connection->config_tree, "Subnet"); @@ -280,7 +352,10 @@ bool setup_myself(void) { if(myself->options & OPTION_TCPONLY) myself->options |= OPTION_INDIRECT; + get_config_bool(lookup_config(config_tree, "DirectOnly"), &directonly); + get_config_bool(lookup_config(config_tree, "StrictSubnets"), &strictsubnets); get_config_bool(lookup_config(config_tree, "TunnelServer"), &tunnelserver); + strictsubnets |= tunnelserver; if(get_config_string(lookup_config(config_tree, "Mode"), &mode)) { if(!strcasecmp(mode, "router")) @@ -294,8 +369,21 @@ bool setup_myself(void) { return false; } free(mode); - } else - routing_mode = RMODE_ROUTER; + } + + if(get_config_string(lookup_config(config_tree, "Forwarding"), &mode)) { + if(!strcasecmp(mode, "off")) + forwarding_mode = FMODE_OFF; + else if(!strcasecmp(mode, "internal")) + forwarding_mode = FMODE_INTERNAL; + else if(!strcasecmp(mode, "kernel")) + forwarding_mode = FMODE_KERNEL; + else { + logger(LOG_ERR, "Invalid forwarding mode!"); + return false; + } + free(mode); + } choice = true; get_config_bool(lookup_config(myself->connection->config_tree, "PMTUDiscovery"), &choice); @@ -426,6 +514,9 @@ bool setup_myself(void) { graph(); + if(strictsubnets) + load_all_subnets(); + /* Open device */ if(!setup_device()) diff --git a/src/netutl.c b/src/netutl.c index b8ecdd1..6acdffa 100644 --- a/src/netutl.c +++ b/src/netutl.c @@ -102,8 +102,10 @@ void sockaddr2str(const sockaddr_t *sa, char **addrstr, char **portstr) { if(scopeid) *scopeid = '\0'; /* Descope. */ - *addrstr = xstrdup(address); - *portstr = xstrdup(port); + if(addrstr) + *addrstr = xstrdup(address); + if(portstr) + *portstr = xstrdup(port); } char *sockaddr2hostname(const sockaddr_t *sa) { diff --git a/src/protocol.c b/src/protocol.c index f09aff6..9d7c349 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -29,6 +29,7 @@ #include "xalloc.h" bool tunnelserver = false; +bool strictsubnets = false; /* Jumptable for the request handlers */ diff --git a/src/protocol.h b/src/protocol.h index 703f74b..2aed26d 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -53,6 +53,7 @@ typedef struct past_request_t { } past_request_t; extern bool tunnelserver; +extern bool strictsubnets; /* Maximum size of strings in a request. * scanf terminates %2048s with a NUL character, diff --git a/src/protocol_auth.c b/src/protocol_auth.c index 06735dc..98d5b61 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -497,7 +497,7 @@ static void send_everything(connection_t *c) { bool ack_h(connection_t *c) { char hisport[MAX_STRING_SIZE]; - char *hisaddress, *dummy; + char *hisaddress; int weight, mtu; uint32_t options; node_t *n; @@ -566,10 +566,9 @@ bool ack_h(connection_t *c) { c->edge = new_edge(); c->edge->from = myself; c->edge->to = n; - sockaddr2str(&c->address, &hisaddress, &dummy); + sockaddr2str(&c->address, &hisaddress, NULL); c->edge->address = str2sockaddr(hisaddress, hisport); free(hisaddress); - free(dummy); c->edge->weight = (weight + c->estimated_weight) / 2; c->edge->connection = c; c->edge->options = c->options; diff --git a/src/protocol_subnet.c b/src/protocol_subnet.c index ba75c89..9ae491d 100644 --- a/src/protocol_subnet.c +++ b/src/protocol_subnet.c @@ -104,29 +104,21 @@ bool add_subnet_h(connection_t *c) { return true; } - /* In tunnel server mode, check if the subnet matches one in the config file of this node */ + /* In tunnel server mode, we should already know all allowed subnets */ if(tunnelserver) { - config_t *cfg; - subnet_t *allowed; + logger(LOG_WARNING, "Ignoring unauthorized %s from %s (%s): %s", + "ADD_SUBNET", c->name, c->hostname, subnetstr); + return true; + } - for(cfg = lookup_config(c->config_tree, "Subnet"); cfg; cfg = lookup_config_next(c->config_tree, cfg)) { - if(!get_config_subnet(cfg, &allowed)) - continue; + /* Ignore if strictsubnets is true, but forward it to others */ - if(!subnet_compare(&s, allowed)) - break; - - free_subnet(allowed); - } - - if(!cfg) { - logger(LOG_WARNING, "Ignoring unauthorized %s from %s (%s): %s", - "ADD_SUBNET", c->name, c->hostname, subnetstr); - return true; - } - - free_subnet(allowed); + if(strictsubnets) { + logger(LOG_WARNING, "Ignoring unauthorized %s from %s (%s): %s", + "ADD_SUBNET", c->name, c->hostname, subnetstr); + forward_request(c); + return true; } /* If everything is correct, add the subnet to the list of the owner */ @@ -139,8 +131,7 @@ bool add_subnet_h(connection_t *c) { /* Tell the rest */ - if(!tunnelserver) - forward_request(c); + forward_request(c); /* Fast handoff of roaming MAC addresses */ @@ -216,6 +207,8 @@ bool del_subnet_h(connection_t *c) { if(!find) { ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) for %s which does not appear in his subnet tree", "DEL_SUBNET", c->name, c->hostname, name); + if(strictsubnets) + forward_request(c); return true; } @@ -228,10 +221,14 @@ bool del_subnet_h(connection_t *c) { return true; } + if(tunnelserver) + return true; + /* Tell the rest */ - if(!tunnelserver) - forward_request(c); + forward_request(c); + if(strictsubnets) + return true; /* Finally, delete it. */ diff --git a/src/route.c b/src/route.c index 664fed8..1caf738 100644 --- a/src/route.c +++ b/src/route.c @@ -33,6 +33,8 @@ #include "utils.h" rmode_t routing_mode = RMODE_ROUTER; +fmode_t forwarding_mode = FMODE_INTERNAL; +bool directonly = false; bool priorityinheritance = false; int macexpire = 600; bool overwrite_mac = false; @@ -48,7 +50,10 @@ static const size_t ip6_size = sizeof(struct ip6_hdr); static const size_t icmp6_size = sizeof(struct icmp6_hdr); static const size_t ns_size = sizeof(struct nd_neighbor_solicit); static const size_t opt_size = sizeof(struct nd_opt_hdr); -#define max(a, b) ((a) > (b) ? (a) : (b)) + +#ifndef MAX +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif /* RFC 1071 */ @@ -94,9 +99,13 @@ static bool checklength(node_t *source, vpn_packet_t *packet, length_t length) { } static void clamp_mss(const node_t *source, const node_t *via, vpn_packet_t *packet) { - if(!via || via == myself || !(via->options & OPTION_CLAMP_MSS)) + if(!source || !via || !(via->options & OPTION_CLAMP_MSS)) return; + uint16_t mtu = source->mtu; + if(via != myself && via->mtu < mtu) + mtu = via->mtu; + /* Find TCP header */ int start = 0; uint16_t type = packet->data[12] << 8 | packet->data[13]; @@ -140,7 +149,7 @@ static void clamp_mss(const node_t *source, const node_t *via, vpn_packet_t *pac /* Found it */ uint16_t oldmss = packet->data[start + 22 + i] << 8 | packet->data[start + 23 + i]; - uint16_t newmss = via->mtu - start - 20; + uint16_t newmss = mtu - start - 20; uint16_t csum = packet->data[start + 16] << 8 | packet->data[start + 17]; if(oldmss <= newmss) @@ -379,17 +388,23 @@ static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) { } if(!subnet->owner->status.reachable) - route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_UNREACH); + return route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_UNREACH); + + if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) + return route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_ANO); if(priorityinheritance) packet->priority = packet->data[15]; via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via; - if(via && packet->len > max(via->mtu, 590) && via != myself) { + if(directonly && subnet->owner != via) + return route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_ANO); + + if(via && packet->len > MAX(via->mtu, 590) && via != myself) { ifdebug(TRAFFIC) logger(LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu); if(packet->data[20] & 0x40) { - packet->len = max(via->mtu, 590); + packet->len = MAX(via->mtu, 590); route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED); } else { fragment_ipv4_packet(via, packet); @@ -527,13 +542,19 @@ static void route_ipv6_unicast(node_t *source, vpn_packet_t *packet) { } if(!subnet->owner->status.reachable) - route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE); + return route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE); + + if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) + return route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN); via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via; - if(via && packet->len > max(via->mtu, 1294) && via != myself) { + if(directonly && subnet->owner != via) + return route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN); + + if(via && packet->len > MAX(via->mtu, 1294) && via != myself) { ifdebug(TRAFFIC) logger(LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu); - packet->len = max(via->mtu, 1294); + packet->len = MAX(via->mtu, 1294); route_ipv6_unreachable(source, packet, ICMP6_PACKET_TOO_BIG, 0); return; } @@ -792,9 +813,15 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { return; } + if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) + return; + // Handle packets larger than PMTU node_t *via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via; + + if(directonly && subnet->owner != via) + return; if(via && packet->len > via->mtu && via != myself) { ifdebug(TRAFFIC) logger(LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu); @@ -820,6 +847,11 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { } void route(node_t *source, vpn_packet_t *packet) { + if(forwarding_mode == FMODE_KERNEL && source != myself) { + send_packet(myself, packet); + return; + } + if(!checklength(source, packet, ether_size)) return; diff --git a/src/route.h b/src/route.h index 1fcc6be..49431f2 100644 --- a/src/route.h +++ b/src/route.h @@ -30,7 +30,15 @@ typedef enum rmode_t { RMODE_ROUTER, } rmode_t; +typedef enum fmode_t { + FMODE_OFF = 0, + FMODE_INTERNAL, + FMODE_KERNEL, +} fmode_t; + extern rmode_t routing_mode; +extern fmode_t forwarding_mode; +extern bool directonly; extern bool overwrite_mac; extern bool priorityinheritance; extern int macexpire; diff --git a/src/subnet.h b/src/subnet.h index b2124a0..e129a95 100644 --- a/src/subnet.h +++ b/src/subnet.h @@ -64,6 +64,8 @@ typedef struct subnet_t { #define MAXNETSTR 64 +extern avl_tree_t *subnet_tree; + extern int subnet_compare(const struct subnet_t *, const struct subnet_t *); extern subnet_t *new_subnet(void) __attribute__ ((__malloc__)); extern void free_subnet(subnet_t *); diff --git a/src/tincd.c b/src/tincd.c index 7779430..3debb3e 100644 --- a/src/tincd.c +++ b/src/tincd.c @@ -37,7 +37,9 @@ #include #include +#ifdef HAVE_LZO #include LZO1X_H +#endif #ifndef HAVE_MINGW #include @@ -540,10 +542,12 @@ int main(int argc, char **argv) { if(!read_server_config()) return 1; +#ifdef HAVE_LZO if(lzo_init() != LZO_E_OK) { logger(LOG_ERR, "Error initializing LZO compressor!"); return 1; } +#endif #ifdef HAVE_MINGW if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) {