diff --git a/COPYING b/COPYING index 2ecad8d..74fe22a 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (C) 1998-2009 Ivo Timmermans, Guus Sliepen and others. +Copyright (C) 1998-2010 Ivo Timmermans, Guus Sliepen and others. See the AUTHORS file for a complete list. This program is free software; you can redistribute it and/or modify it under diff --git a/COPYING.README b/COPYING.README index efeb98c..2eb9c1f 100644 --- a/COPYING.README +++ b/COPYING.README @@ -15,3 +15,5 @@ The following applies to the LZO library: When tinc is compiled with the --enable-tunemu option, the resulting binary falls under the GPL version 3 or later. + + diff --git a/ChangeLog b/ChangeLog index 0f3aeef..7487d17 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,195 @@ +commit f7b2a2ea43fca323f543e152e6a43a29a4eb6671 +Author: Guus Sliepen +Date: Wed Feb 3 22:49:48 2010 +0100 + + Releasing 1.0.12. + +commit cd0c2e86a403fc9aabecdc8d51413f94491b5494 +Author: Guus Sliepen +Date: Wed Feb 3 11:18:46 2010 +0100 + + Ensure peers with a meta connection always have our key. + + This keeps UDP probes going, which in turn keeps NAT mappings alive. + +commit 40d91ff619a6ea24a2a35c9d934bcc6bace27e24 +Author: Guus Sliepen +Date: Tue Feb 2 22:49:21 2010 +0100 + + Update copyright notices. + +commit 44f8f61396a92c899172a1863bbc9c705cbfa649 +Author: Guus Sliepen +Date: Tue Feb 2 22:22:27 2010 +0100 + + Try to set DF bit on BSDs as well. + + Every operating system seems to have its own, slightly different way to disable + packet fragmentation. Emit a compiler warning when no suitable way is found. + On OpenBSD, it seems impossible to do it for IPv4. + +commit ed14ef93b47622ba13099dfc6be5335222e987a6 +Author: Guus Sliepen +Date: Tue Feb 2 01:02:40 2010 +0100 + + Immediately exchange keys when establishing a meta connection. + + This in turn will trigger PMTU discovery, and ensures nodes know each others + reflexive UDP address and port. + +commit 4a0b9981513059755b9fd15b38fc198f46a0d6f2 +Author: Guus Sliepen +Date: Tue Feb 2 00:51:44 2010 +0100 + + Determine peer's reflexive address and port when exchanging keys. + + To help peers that are behind NAT connect to each other directly via UDP, they + need to know the exact external address and port that they use. Keys exchanged + between NATted peers necessarily go via a third node, which knows this address + and port, and can append this information to the keys, which is in turned used + by the peers. + + Since PMTU discovery will immediately trigger UDP communication from both sides + to each other, this should allow direct communication between peers behind + full, address-restricted and port-restricted cone NAT. + +commit d15099e0029578bfd24d6b464b941f4693280001 +Author: Guus Sliepen +Date: Sat Jan 23 18:48:01 2010 +0100 + + Be liberal in accepting KEY_CHANGED/REQ_KEY/ANS_KEY requests. + + When we got a key request for or from a node we don't know, we disconnected the + node that forwarded us that request. However, especially in TunnelServer mode, + disconnecting does not help. We now ignore such requests, but since there is no + way of telling the original sender that the request was dropped, we now retry + sending REQ_KEY requests when we don't get an ANS_KEY back. + +commit 469fa318bc817908af9a51e3a980ffc998fae6f2 +Author: Guus Sliepen +Date: Fri Jan 22 21:59:40 2010 +0100 + + Run subnet-up/down scripts for local MAC addresses as well. + +commit 5d194b9f8767390d9fb1170554a8b6928214957a +Author: Guus Sliepen +Date: Fri Jan 22 21:47:26 2010 +0100 + + Fix subnet-up/down scripts being called with an empty SUBNET. + + Commit 052ff8b2c598358d1c5febaa9f9f5fc5d384cfd3 contained a bug that causes + scripts to be called with an empty, or possibly corrupted SUBNET variable when + a Subnet is added or removed while the owner is still online. In router mode, + this normally does not happen, but in switch mode this is normal. + +commit b45511118421920771f5dcd5e4bafc04376e4450 +Author: Guus Sliepen +Date: Sat Jan 16 20:16:33 2010 +0100 + + Make MSS clamping configurable, but enabled by default. + + It can either be set globally in tinc.conf, or per-node in host config files. + +commit 95928f7c2910a7da01a89cdc63c86c4d87fac004 +Author: Guus Sliepen +Date: Sat Jan 16 19:32:33 2010 +0100 + + Also clamp MSS of TCP over IPv6 packets. + +commit b1945f70fe993ca447555a1e27f35638b0c1fd8b +Author: Guus Sliepen +Date: Fri Jan 15 23:41:14 2010 +0100 + + Optimise handling of select() returning <= 0. + + Before, we immediately retried select() if it returned -1 and errno is EAGAIN + or EINTR, and if it returned 0 it would check for network events even if we + know there are none. Now, if -1 or 0 is returned we skip checking network + events, but we do check for timer and signal events. + +commit 51099658c919794cde72ea1107b9d9b9c3cee926 +Author: Guus Sliepen +Date: Fri Jan 15 23:19:08 2010 +0100 + + Ping nodes immediately when receiving SIGALRM. + + One reason to send the ALRM signal is to let tinc immediately try to connect to + outgoing nodes, for example when PPP or DHCP configuration of the outgoing + interface finished. Conversely, when the outgoing interface goes down one can + now send this signal to let tinc quickly detect that links are down too. + +commit 2a538ed34332b3392f866d56accd9efecc9467ed +Author: Guus Sliepen +Date: Fri Jan 15 13:42:37 2010 +0100 + + Clamp MSS of IPv4 SYN packets. + + Some ISPs block the ICMP Fragmentation Needed packets that tinc sends. We + clamp the MSS of IPv4 SYN packets to prevent hosts behind those ISPs from + sending too large packets. + +commit e4812ba9cc4262ec921944f02639ce55781d7497 +Author: Guus Sliepen +Date: Thu Dec 24 12:42:21 2009 +0100 + + Allow Port and PMTUDiscovery options in tinc.conf, always enable PMTUDiscovery by default. + +commit 7203d5fb07be2d3ae006c2b65d0be1e6533e1273 +Author: Guus Sliepen +Date: Wed Dec 23 19:51:55 2009 +0100 + + Use xstrdup() instead of xasprintf() to copy static strings. + +commit a9a803d5662832eb397837055a49fd94118eabf3 +Author: Guus Sliepen +Date: Wed Dec 23 19:49:38 2009 +0100 + + Allow port to be specified in Address statements. + + This allows one to connect to use more than one port number to connect to + another node. The syntax is now: + + Address = [] + +commit 43e34d8180c90682ed1601dec3de7f68ec96d65b +Author: Guus Sliepen +Date: Wed Dec 23 19:22:06 2009 +0100 + + Do not fragment packets smaller than RFC defined minimum MTUs. + + For IPv6, the minimum MTU is 1280 (RFC 2460), for IPv4 the minimum is actually + 68, but this is such a low limit that it will probably hurt performance, so we + do as if it is 576 (the minimum packet size hosts should be able to handle, RFC + 791). If we detect a path MTU smaller than those minima, and we have to handle + a packet that is bigger than the PMTU but smaller than those minima, we forward + them via TCP instead of fragmenting or returning ICMP packets. + +commit 369fe1ab1cbfc3f8305de1faab2e30157378b044 +Author: Guus Sliepen +Date: Tue Dec 8 22:18:37 2009 +0000 + + Forget addresses of unreachable nodes. + + We clear the cached address used for UDP connections when a node becomes + unreachable. This also prevents host-up scripts from passing the old, cached + address from when the host becomes reachable again from a different address. + +commit 62f235e05c54e458724f437e519ed1b3e17835b1 +Author: Guus Sliepen +Date: Sat Nov 28 11:56:13 2009 +0000 + + Remove unused variable in lookup_subnet_*() functions. + +commit 92aefd25bf9e8e63f199cc252218f5c427f836b7 +Author: Guus Sliepen +Date: Sat Nov 28 11:52:23 2009 +0000 + + When learning MAC addresses, only check our own Subnets for previous entries. + + Before it would check all addresses, and not learn an address if another node + already claimed that address. This caused fast roaming to fail, the code from + commit 6f6f426b353596edca77829c0477268fc2fc1925 was never triggered. + commit 44834d030464bbe1f7733caba8d96c678f1d6cf2 Author: Guus Sliepen Date: Sun Nov 1 16:24:39 2009 +0100 diff --git a/INSTALL b/INSTALL index 2550dab..7d1c323 100644 --- a/INSTALL +++ b/INSTALL @@ -4,8 +4,10 @@ Installation Instructions Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. - This file is free documentation; the Free Software Foundation gives -unlimited permission to copy, distribute and modify it. + Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without warranty of any kind. Basic Installation ================== @@ -13,7 +15,11 @@ Basic Installation Briefly, the shell commands `./configure; make; make install' should configure, build, and install this package. The following more-detailed instructions are generic; see the `README' file for -instructions specific to this package. +instructions specific to this package. Some packages provide this +`INSTALL' file but do not implement all of the features documented +below. The lack of an optional feature in a given package is not +necessarily a bug. More recommendations for GNU packages can be found +in *note Makefile Conventions: (standards)Makefile Conventions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses @@ -42,7 +48,7 @@ may remove or edit it. you want to change it or regenerate `configure' using a newer version of `autoconf'. -The simplest way to compile this package is: + The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. @@ -53,12 +59,22 @@ The simplest way to compile this package is: 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with - the package. + the package, generally using the just-built uninstalled binaries. 4. Type `make install' to install the programs and any data files and - documentation. + documentation. When installing into a prefix owned by root, it is + recommended that the package be configured and built as a regular + user, and only the `make install' phase executed with root + privileges. - 5. You can remove the program binaries and object files from the + 5. Optionally, type `make installcheck' to repeat any self-tests, but + this time using the binaries in their final installed location. + This target does not install anything. Running this target as a + regular user, particularly if the prior `make install' required + root privileges, verifies that the installation completed + correctly. + + 6. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is @@ -67,8 +83,15 @@ The simplest way to compile this package is: all sorts of other programs in order to regenerate files that came with the distribution. - 6. Often, you can also type `make uninstall' to remove the installed - files again. + 7. Often, you can also type `make uninstall' to remove the installed + files again. In practice, not all packages have tested that + uninstallation works correctly, even though it is required by the + GNU Coding Standards. + + 8. Some packages, particularly those that use Automake, provide `make + distcheck', which can by used by developers to test that all other + targets like `make install' and `make uninstall' work correctly. + This target is generally not run by end users. Compilers and Options ===================== @@ -93,7 +116,8 @@ same time, by placing the object files for each architecture in their own directory. To do this, you can use GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. +source code in the directory that `configure' is in and in `..'. This +is known as a "VPATH" build. With a non-GNU `make', it is safer to compile the package for one architecture at a time in the source code directory. After you have @@ -120,7 +144,8 @@ Installation Names By default, `make install' installs the package's commands under `/usr/local/bin', include files under `/usr/local/include', etc. You can specify an installation prefix other than `/usr/local' by giving -`configure' the option `--prefix=PREFIX'. +`configure' the option `--prefix=PREFIX', where PREFIX must be an +absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you @@ -131,15 +156,46 @@ Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=DIR' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. +you can set and what kinds of files go in them. In general, the +default for these options is expressed in terms of `${prefix}', so that +specifying just `--prefix' will affect all of the other directory +specifications that were not explicitly provided. + + The most portable way to affect installation locations is to pass the +correct locations to `configure'; however, many packages provide one or +both of the following shortcuts of passing variable assignments to the +`make install' command line to change installation locations without +having to reconfigure or recompile. + + The first method involves providing an override variable for each +affected directory. For example, `make install +prefix=/alternate/directory' will choose an alternate location for all +directory configuration variables that were expressed in terms of +`${prefix}'. Any directories that were specified during `configure', +but not in terms of `${prefix}', must each be overridden at install +time for the entire installation to be relocated. The approach of +makefile variable overrides for each directory variable is required by +the GNU Coding Standards, and ideally causes no recompilation. +However, some platforms have known limitations with the semantics of +shared libraries that end up requiring recompilation when using this +method, particularly noticeable in packages that use GNU Libtool. + + The second method involves providing the `DESTDIR' variable. For +example, `make install DESTDIR=/alternate/directory' will prepend +`/alternate/directory' before all installation names. The approach of +`DESTDIR' overrides is not required by the GNU Coding Standards, and +does not work on platforms that have drive letters. On the other hand, +it does better at avoiding recompilation issues, and works well even +when some directory options were not specified in terms of `${prefix}' +at `configure' time. + +Optional Features +================= If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. -Optional Features -================= - Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE @@ -152,6 +208,13 @@ find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. + Some packages offer the ability to configure how verbose the +execution of `make' will be. For these packages, running `./configure +--enable-silent-rules' sets the default to minimal output, which can be +overridden with `make V=1'; while running `./configure +--disable-silent-rules' sets the default to verbose, which can be +overridden with `make V=0'. + Particular systems ================== @@ -288,7 +351,7 @@ operates. `configure' can determine that directory automatically. `--prefix=DIR' - Use DIR as the installation prefix. *Note Installation Names:: + Use DIR as the installation prefix. *note Installation Names:: for more details, including other options available for fine-tuning the installation locations. diff --git a/Makefile.in b/Makefile.in index b3e277d..837e15d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -269,7 +269,7 @@ distclean-hdr: # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): - @failcom='exit 1'; \ + @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ @@ -294,7 +294,7 @@ $(RECURSIVE_TARGETS): fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): - @failcom='exit 1'; \ + @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ @@ -458,7 +458,8 @@ distdir: $(DISTFILES) fi; \ done -test -n "$(am__skip_mode_fix)" \ - || find "$(distdir)" -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ @@ -502,17 +503,17 @@ dist dist-all: distdir distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ - GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ - bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lzma*) \ - unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\ + lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ - GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac diff --git a/NEWS b/NEWS index 330efbc..942398e 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,18 @@ +Version 1.0.12 Feb 3 2010 + + * Really allow fast roaming of hosts to other nodes in a switched VPN. + + * Fixes missing or incorrect environment variables when calling host-up/down + and subnet-up/down scripts in some cases. + + * Allow port to be specified in Address statements. + + * Clamp MSS of TCP packets to the discovered path MTU. + + * Let two nodes behind NAT learn each others current UDP address and port via + a third node, potentially allowing direct communications in a similar way to + STUN. + Version 1.0.11 Nov 1 2009 * Fixed potential crash when the HUP signal is sent. diff --git a/README b/README index 8f76b15..9cc1042 100644 --- a/README +++ b/README @@ -1,7 +1,7 @@ -This is the README file for tinc version 1.0.11. Installation +This is the README file for tinc version 1.0.12. Installation instructions may be found in the INSTALL file. -tinc is Copyright (C) 1998-2009 by: +tinc is Copyright (C) 1998-2010 by: Ivo Timmermans, Guus Sliepen , @@ -55,7 +55,7 @@ should be changed into "Device", and "Device" should be changed into Compatibility ------------- -Version 1.0.11 is compatible with 1.0pre8, 1.0 and later, but not with older +Version 1.0.12 is compatible with 1.0pre8, 1.0 and later, but not with older versions of tinc. diff --git a/aclocal.m4 b/aclocal.m4 index 1343274..912b927 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,4 +1,4 @@ -# generated automatically by aclocal 1.11 -*- Autoconf -*- +# generated automatically by aclocal 1.11.1 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. @@ -13,8 +13,8 @@ m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.64],, -[m4_warning([this file was generated for autoconf 2.64. +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.65],, +[m4_warning([this file was generated for autoconf 2.65. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically `autoreconf'.])]) @@ -34,7 +34,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.11' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.11], [], +m4_if([$1], [1.11.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -50,7 +50,7 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.11])dnl +[AM_AUTOMAKE_VERSION([1.11.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) diff --git a/configure b/configure index 21baffb..aaaa854 100755 --- a/configure +++ b/configure @@ -1,10 +1,12 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.64. +# Generated by GNU Autoconf 2.65. +# # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software -# Foundation, Inc. +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. @@ -524,7 +526,8 @@ as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" -exec 7<&0 &1 +test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, @@ -1364,7 +1367,7 @@ Some influential environment variables: LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l - CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor @@ -1435,7 +1438,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF configure -generated by GNU Autoconf 2.64 +generated by GNU Autoconf 2.65 Copyright (C) 2009 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation @@ -1482,7 +1485,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - return $ac_retval + as_fn_set_status $ac_retval } # ac_fn_c_try_compile @@ -1519,7 +1522,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - return $ac_retval + as_fn_set_status $ac_retval } # ac_fn_c_try_cpp @@ -1648,7 +1651,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - return $ac_retval + as_fn_set_status $ac_retval } # ac_fn_c_try_run @@ -1779,7 +1782,7 @@ fi # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - return $ac_retval + as_fn_set_status $ac_retval } # ac_fn_c_try_link @@ -1893,7 +1896,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was -generated by GNU Autoconf 2.64. Invocation command line was +generated by GNU Autoconf 2.65. Invocation command line was $ $0 $@ @@ -2146,7 +2149,7 @@ fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue - if test -r "$ac_site_file"; then + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 @@ -2155,9 +2158,9 @@ $as_echo "$as_me: loading site script $ac_site_file" >&6;} done if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special - # files actually), so we avoid doing that. - if test -f "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in @@ -2577,6 +2580,7 @@ IFS=$as_save_IFS fi + test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else @@ -2584,7 +2588,6 @@ fi # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. - test -d ./--version && rmdir ./--version MKDIR_P="$ac_install_sh -d" fi fi @@ -2701,7 +2704,7 @@ fi # Define the identity of the package. PACKAGE=tinc - VERSION=1.0.11 + VERSION=1.0.12 cat >>confdefs.h <<_ACEOF @@ -3154,32 +3157,30 @@ $as_echo "$ac_try_echo"; } >&5 ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 - rm -f conftest.er1 conftest.err fi + rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include + int main () { -FILE *f = fopen ("conftest.out", "w"); - return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out conftest.out" +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 -$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: @@ -3241,10 +3242,10 @@ test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 -$as_echo "$ac_file" >&6; } if test -z "$ac_file"; then : - $as_echo "$as_me: failed program was:" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 @@ -3252,51 +3253,18 @@ $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { as_fn_set_status 77 as_fn_error "C compiler cannot create executables See \`config.log' for more details." "$LINENO" 5; }; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 -$as_echo_n "checking whether the C compiler works... " >&6; } -# If not cross compiling, check that we can run a simple program. -if test "$cross_compiling" != yes; then - if { ac_try='./$ac_file' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error "cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." "$LINENO" 5; } - fi - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out conftest.out +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 -$as_echo_n "checking whether we are cross compiling... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 -$as_echo "$cross_compiling" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" @@ -3329,13 +3297,72 @@ $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." "$LINENO" 5; } fi -rm -f conftest$ac_cv_exeext +rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if test "${ac_cv_objext+set}" = set; then : @@ -7118,7 +7145,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # values after options handling. ac_log=" This file was extended by $as_me, which was -generated by GNU Autoconf 2.64. Invocation command line was +generated by GNU Autoconf 2.65. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -7158,6 +7185,7 @@ Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit + --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files @@ -7180,10 +7208,11 @@ Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ config.status -configured by $0, generated by GNU Autoconf 2.64, - with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" +configured by $0, generated by GNU Autoconf 2.65, + with options \\"\$ac_cs_config\\" Copyright (C) 2009 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation @@ -7221,6 +7250,8 @@ do ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) @@ -7412,7 +7443,7 @@ s/'"$ac_delim"'$// t delim :nl h -s/\(.\{148\}\).*/\1/ +s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p @@ -7426,7 +7457,7 @@ s/.\{148\}// t nl :delim h -s/\(.\{148\}\).*/\1/ +s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p diff --git a/configure.in b/configure.in index 21a5818..df15067 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.11) +AM_INIT_AUTOMAKE(tinc, 1.0.12) AC_CONFIG_HEADERS([config.h]) AM_MAINTAINER_MODE diff --git a/debian/changelog b/debian/changelog index cd71b80..b46ee18 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,19 @@ +tinc (1.0.12-1~bpo50) lenny-backports; urgency=low + + * New upstream release. + * Keep debian/ from 1.0.11-1~bpo50. + * Use init.d script from Michael Tokarev, allowing per-network arguments to + tincd. + * Let the init.d script depend on $remote_fs. + + -- Guus Sliepen Wed, 17 Feb 2010 22:00:31 +0000 + +tinc (1.0.11-1~bpo50+1) lenny-backports; urgency=low + + * Rebuild for lenny-backports. + + -- Guus Sliepen Thu, 04 Feb 2010 19:03:00 +0000 + tinc (1.0.11-1) unstable; urgency=low * New upstream release. diff --git a/debian/init.d b/debian/init.d index ce77497..a7dd3cd 100644 --- a/debian/init.d +++ b/debian/init.d @@ -2,8 +2,8 @@ # ### BEGIN INIT INFO # Provides: tinc -# Required-Start: $network -# Required-Stop: $network +# Required-Start: $remote_fs $network +# Required-Stop: $remote_fs $network # Should-Start: $syslog $named # Should-Stop: $syslog # Default-Start: 2 3 4 5 @@ -29,52 +29,47 @@ test -f $DAEMON || exit 0 [ -r /etc/default/tinc ] && . /etc/default/tinc -find_nets () { +# foreach_net "what-to-say" action [arguments...] +foreach_net() { if [ ! -f $NETSFILE ] ; then echo "Please create $NETSFILE." exit 0 fi - NETS="`egrep '^[ ]*[a-zA-Z0-9_-]+[ ]*$' $NETSFILE`" + echo -n "$1" + shift + egrep '^[ ]*[a-zA-Z0-9_-]+' $NETSFILE | while read net args; do + echo -n " $net" + "$@" $net $args + done + echo "." +} + +start() { + $DAEMON $EXTRA -n "$@" +} +stop() { + $DAEMON -n $1 -k +} +reload() { + $DAEMON -n $1 -kHUP +} +restart() { + stop "$@" && sleep 1 + start "$@" } case "$1" in start) - find_nets - echo -n "Starting $DESC:" - for n in $NETS ; do - echo -n " $n" - $DAEMON -n $n $EXTRA - done - echo "." + foreach_net "Starting $DESC:" start ;; stop) - find_nets - echo -n "Stopping $DESC:" - for n in $NETS ; do - echo -n " $n" - $DAEMON -n $n $EXTRA -k - done - echo "." + foreach_net "Stopping $DESC:" stop ;; reload|force-reload) - find_nets - echo -n "Reloading $DESC configuration:" - for n in $NETS ; do - echo -n " $n" - $DAEMON -n $n $EXTRA -kHUP - done - echo "." + foreach_net "Reloading $DESC configuration:" reload ;; restart) - find_nets - echo -n "Restarting $DESC:" - for n in $NETS ; do - echo -n " $n" - $DAEMON -n $n $EXTRA -k - sleep 1 - $DAEMON -n $n $EXTRA - done - echo "." + foreach_net "Restarting $DESC:" restart ;; *) echo "Usage: /etc/init.d/$NAME {start|stop|reload|restart|force-reload}" diff --git a/doc/Makefile.in b/doc/Makefile.in index 218fd63..44c4161 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/doc/sample-config.tar.gz b/doc/sample-config.tar.gz index 28172a6..da56735 100644 Binary files a/doc/sample-config.tar.gz and b/doc/sample-config.tar.gz differ diff --git a/doc/texinfo.tex b/doc/texinfo.tex index 0d3ba16..9140826 100644 --- a/doc/texinfo.tex +++ b/doc/texinfo.tex @@ -1,9 +1,9 @@ % texinfo.tex -- TeX macros to handle Texinfo files. -% +% % Load plain if necessary, i.e., if running under initex. \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi % -\def\texinfoversion{2009-05-16.16} +\def\texinfoversion{2009-08-14.15} % % Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, % 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, @@ -1332,13 +1332,16 @@ output) for that.)} \ifpdf % - % Color manipulation macros based on pdfcolor.tex. - \def\cmykDarkRed{0.28 1 1 0.35} - \def\cmykBlack{0 0 0 1} + % Color manipulation macros based on pdfcolor.tex, + % except using rgb instead of cmyk; the latter is said to render as a + % very dark gray on-screen and a very dark halftone in print, instead + % of actual black. + \def\rgbDarkRed{0.50 0.09 0.12} + \def\rgbBlack{0 0 0} % % k sets the color for filling (usual text, etc.); % K sets the color for stroking (thin rules, e.g., normal _'s). - \def\pdfsetcolor#1{\pdfliteral{#1 k #1 K}} + \def\pdfsetcolor#1{\pdfliteral{#1 rg #1 RG}} % % Set color, and create a mark which defines \thiscolor accordingly, % so that \makeheadline knows which color to restore. @@ -1348,7 +1351,7 @@ output) for that.)} \pdfsetcolor{#1}% } % - \def\maincolor{\cmykBlack} + \def\maincolor{\rgbBlack} \pdfsetcolor{\maincolor} \edef\thiscolor{\maincolor} \def\lastcolordefs{} @@ -1443,8 +1446,8 @@ output) for that.)} % % by default, use a color that is dark enough to print on paper as % nearly black, but still distinguishable for online viewing. - \def\urlcolor{\cmykDarkRed} - \def\linkcolor{\cmykDarkRed} + \def\urlcolor{\rgbDarkRed} + \def\linkcolor{\rgbDarkRed} \def\endlink{\setcolor{\maincolor}\pdfendlink} % % Adding outlines to PDF; macros for calculating structure of outlines @@ -4322,6 +4325,7 @@ end \definedummyword\code \definedummyword\command \definedummyword\dfn + \definedummyword\email \definedummyword\emph \definedummyword\env \definedummyword\file @@ -9272,12 +9276,8 @@ directory should work if nowhere else does.} @markupsetuplqdefault @markupsetuprqdefault -@c Gnulib now utterly and painfully insists on no trailing whitespace. -@c So we have to nuke it. - @c Local variables: @c eval: (add-hook 'write-file-hooks 'time-stamp) -@c eval: (add-hook 'write-file-hooks 'nuke-trailing-whitespace) @c page-delimiter: "^\\\\message" @c time-stamp-start: "def\\\\texinfoversion{" @c time-stamp-format: "%:y-%02m-%02d.%02H" diff --git a/doc/tinc.conf.5.in b/doc/tinc.conf.5.in index 1cb2f0c..e6b3553 100644 --- a/doc/tinc.conf.5.in +++ b/doc/tinc.conf.5.in @@ -1,4 +1,4 @@ -.Dd 2009-03-05 +.Dd 2010-01-16 .Dt TINC.CONF 5 .\" Manual page created by: .\" Ivo Timmermans @@ -330,9 +330,10 @@ Since host configuration files only contain public keys, no secrets are revealed by sending out this information. .Bl -tag -width indent -.It Va Address Li = Ar address Bq recommended +.It Va Address Li = Ar address Oo port Oc Bq recommended The IP address or hostname of this tinc daemon on the real network. This will only be used when trying to make an outgoing connection to this tinc daemon. +Optionally, a port can be specified to use for this address. Multiple .Va Address variables can be specified, in which case each address will be tried until a working @@ -346,6 +347,11 @@ Furthermore, specifying will turn off packet encryption. It is best to use only those ciphers which support CBC mode. +.It Va ClampMSS Li = yes | no Pq yes +This option specifies whether tinc should clamp the maximum segment size (MSS) +of TCP packets to the path MTU. This helps in situations where ICMP +Fragmentation Needed or Packet too Big messages are dropped by firewalls. + .It Va Compression Li = Ar level Pq 0 This option sets the level of compression used for UDP packets. Possible values are 0 (off), 1 (fast zlib) and any integer up to 9 (best zlib), @@ -380,7 +386,10 @@ When this option is enabled, tinc will try to discover the path MTU to this node After the path MTU has been discovered, it will be enforced on the VPN. .It Va Port Li = Ar port Pq 655 -The port number on which this tinc daemon is listening for incoming connections. +The port number on which this tinc daemon is listening for incoming connections, +which is used if no port number is specified in an +.Va Address +statement. .It Va PublicKey Li = Ar key Bq obsolete The public RSA key of this tinc daemon. diff --git a/doc/tinc.info b/doc/tinc.info index 8af5678..ff4088f 100644 --- a/doc/tinc.info +++ b/doc/tinc.info @@ -5,10 +5,10 @@ START-INFO-DIR-ENTRY * tinc: (tinc). The tinc Manual. END-INFO-DIR-ENTRY - This is the info manual for tinc version 1.0.11, a Virtual Private + This is the info manual for tinc version 1.0.12, a Virtual Private Network daemon. - Copyright (C) 1998-2009 Ivo Timmermans, Guus Sliepen + Copyright (C) 1998-2010 Ivo Timmermans, Guus Sliepen and Wessel Dankers . Permission is granted to make and distribute verbatim copies of this @@ -855,10 +855,11 @@ File: tinc.info, Node: Host configuration variables, Next: Scripts, Prev: Mai 4.4.2 Host configuration variables ---------------------------------- -Address = [recommended] +Address = [] [recommended] This variable is only required if you want to connect to this host. It must resolve to the external IP address where the host - can be reached, not the one that is internal to the VPN. + can be reached, not the one that is internal to the VPN. If no + port is specified, the default Port is used. Cipher = (blowfish) The symmetric cipher algorithm used to encrypt UDP packets. Any @@ -866,6 +867,12 @@ Cipher = (blowfish) specifying "none" will turn off packet encryption. It is best to use only those ciphers which support CBC mode. +ClampMSS = (yes) + This option specifies whether tinc should clamp the maximum + segment size (MSS) of TCP packets to the path MTU. This helps in + situations where ICMP Fragmentation Needed or Packet too Big + messages are dropped by firewalls. + Compression = (0) This option sets the level of compression used for UDP packets. Possible values are 0 (off), 1 (fast zlib) and any integer up to 9 @@ -2224,14 +2231,16 @@ Concept Index * CHALLENGE: Authentication protocol. (line 10) * CIDR notation: Host configuration variables. - (line 85) + (line 92) * Cipher: Host configuration variables. - (line 11) + (line 12) +* ClampMSS: Host configuration variables. + (line 18) * client: How connections work. (line 18) * command line: Runtime options. (line 9) * Compression: Host configuration variables. - (line 17) + (line 24) * connection: The connection. (line 6) * ConnectTo: Main configuration variables. (line 27) @@ -2248,7 +2257,7 @@ Concept Index * DeviceType: Main configuration variables. (line 45) * Digest: Host configuration variables. - (line 22) + (line 29) * encapsulating: The UDP tunnel. (line 30) * encryption: Encryption of network packets. (line 6) @@ -2265,7 +2274,7 @@ Concept Index * ID: Authentication protocol. (line 10) * IndirectData: Host configuration variables. - (line 27) + (line 34) * INTERFACE: Scripts. (line 58) * Interface: Main configuration variables. (line 91) @@ -2280,7 +2289,7 @@ Concept Index * MACExpire: Main configuration variables. (line 133) * MACLength: Host configuration variables. - (line 35) + (line 42) * meta-protocol: The meta-connection. (line 18) * META_KEY: Authentication protocol. (line 10) @@ -2299,7 +2308,7 @@ Concept Index * OpenSSL: OpenSSL. (line 6) * options: Runtime options. (line 9) * PEM format: Host configuration variables. - (line 60) + (line 67) * PING: The meta-protocol. (line 89) * PingInterval: Main configuration variables. (line 143) @@ -2307,12 +2316,12 @@ Concept Index (line 147) * platforms: Supported platforms. (line 6) * PMTU: Host configuration variables. - (line 40) + (line 47) * PMTUDiscovery: Host configuration variables. - (line 43) + (line 50) * PONG: The meta-protocol. (line 89) * Port: Host configuration variables. - (line 48) + (line 55) * port numbers: Other files. (line 17) * PriorityInheritance: Main configuration variables. (line 153) @@ -2325,9 +2334,9 @@ Concept Index * ProcessPriority: Main configuration variables. (line 172) * PublicKey: Host configuration variables. - (line 52) + (line 59) * PublicKeyFile: Host configuration variables. - (line 55) + (line 62) * release: Supported platforms. (line 14) * REMOTEADDRESS: Scripts. (line 67) * REMOTEPORT: Scripts. (line 70) @@ -2343,15 +2352,15 @@ Concept Index * signals: Signals. (line 6) * SUBNET: Scripts. (line 74) * Subnet: Host configuration variables. - (line 67) + (line 74) * Subnet weight: Host configuration variables. - (line 90) + (line 97) * SVPN: Security. (line 11) * switch: Main configuration variables. (line 111) * TCP: The meta-connection. (line 10) * TCPonly: Host configuration variables. - (line 97) + (line 104) * TINC: Security. (line 6) * tinc: Introduction. (line 6) * tinc-down: Scripts. (line 18) @@ -2416,33 +2425,33 @@ Node: How connections work22594 Node: Configuration files23816 Node: Main configuration variables24823 Node: Host configuration variables32865 -Node: Scripts37942 -Node: How to configure40712 -Node: Generating keypairs41975 -Node: Network interfaces42474 -Node: Example configuration44322 -Node: Running tinc49634 -Node: Runtime options50224 -Node: Signals53019 -Node: Debug levels54088 -Node: Solving problems55024 -Node: Error messages56576 -Node: Sending bug reports60589 -Node: Technical information61541 -Node: The connection61772 -Node: The UDP tunnel62084 -Node: The meta-connection65145 -Node: The meta-protocol66614 -Node: Security71623 -Node: Authentication protocol72753 -Node: Encryption of network packets77757 -Node: Security issues79130 -Node: Platform specific information80747 -Node: Interface configuration80975 -Node: Routes82874 -Node: About us84790 -Node: Contact information84965 -Node: Authors85369 -Node: Concept Index85774 +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  End Tag Table diff --git a/doc/tinc.texi b/doc/tinc.texi index e6e6a42..71babb1 100644 --- a/doc/tinc.texi +++ b/doc/tinc.texi @@ -15,7 +15,7 @@ This is the info manual for @value{PACKAGE} version @value{VERSION}, a Virtual Private Network daemon. -Copyright @copyright{} 1998-2009 Ivo Timmermans, +Copyright @copyright{} 1998-2010 Ivo Timmermans, Guus Sliepen and Wessel Dankers . @@ -39,7 +39,7 @@ permission notice identical to this one. @vskip 0pt plus 1filll This is the info manual for @value{PACKAGE} version @value{VERSION}, a Virtual Private Network daemon. -Copyright @copyright{} 1998-2009 Ivo Timmermans, +Copyright @copyright{} 1998-2010 Ivo Timmermans, Guus Sliepen and Wessel Dankers . @@ -943,10 +943,11 @@ and will only allow nodes and subnets on the VPN which are present in the @table @asis @cindex Address -@item Address = <@var{IP address}|@var{hostname}> [recommended] +@item Address = <@var{IP address}|@var{hostname}> [] [recommended] This variable is only required if you want to connect to this host. It must resolve to the external IP address where the host can be reached, not the one that is internal to the VPN. +If no port is specified, the default Port is used. @cindex Cipher @item Cipher = <@var{cipher}> (blowfish) @@ -955,6 +956,12 @@ Any cipher supported by OpenSSL is recognized. Furthermore, specifying "none" will turn off packet encryption. It is best to use only those ciphers which support CBC mode. +@cindex ClampMSS +@item ClampMSS = (yes) +This option specifies whether tinc should clamp the maximum segment size (MSS) +of TCP packets to the path MTU. This helps in situations where ICMP +Fragmentation Needed or Packet too Big messages are dropped by firewalls. + @cindex Compression @item Compression = <@var{level}> (0) This option sets the level of compression used for UDP packets. diff --git a/lib/Makefile.in b/lib/Makefile.in index a2ed27f..1ca27bb 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/m4/Makefile.in b/m4/Makefile.in index f585238..a1736b8 100644 --- a/m4/Makefile.in +++ b/m4/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/src/Makefile.in b/src/Makefile.in index 1f9e7f5..98de5f4 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/src/connection.h b/src/connection.h index b3a7e33..5aac4a6 100644 --- a/src/connection.h +++ b/src/connection.h @@ -1,6 +1,6 @@ /* connection.h -- header for connection.c - Copyright (C) 2000-2009 Guus Sliepen , + Copyright (C) 2000-2010 Guus Sliepen , 2000-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -29,6 +29,7 @@ #define OPTION_INDIRECT 0x0001 #define OPTION_TCPONLY 0x0002 #define OPTION_PMTU_DISCOVERY 0x0004 +#define OPTION_CLAMP_MSS 0x0008 typedef struct connection_status_t { int pinged:1; /* sent ping */ diff --git a/src/graph.c b/src/graph.c index 148f23c..1e6043d 100644 --- a/src/graph.c +++ b/src/graph.c @@ -1,6 +1,6 @@ /* graph.c -- graph algorithms - Copyright (C) 2001-2009 Guus Sliepen , + Copyright (C) 2001-2010 Guus Sliepen , 2001-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -53,6 +53,7 @@ #include "netutl.h" #include "node.h" #include "process.h" +#include "protocol.h" #include "subnet.h" #include "utils.h" #include "xalloc.h" @@ -251,7 +252,7 @@ void sssp_bfs(void) { /* TODO: only clear status.validkey if node is unreachable? */ n->status.validkey = false; - n->status.waitingforkey = false; + n->last_req_key = 0; n->maxmtu = MTU; n->minmtu = 0; @@ -286,6 +287,11 @@ void sssp_bfs(void) { free(envp[i]); subnet_update(n, NULL, n->status.reachable); + + if(!n->status.reachable) + update_node_udp(n, NULL); + else if(n->connection) + send_ans_key(n); } } } diff --git a/src/net.c b/src/net.c index 3f17083..feec8d6 100644 --- a/src/net.c +++ b/src/net.c @@ -1,7 +1,7 @@ /* net.c -- most of the network code Copyright (C) 1998-2005 Ivo Timmermans, - 2000-2009 Guus Sliepen + 2000-2010 Guus Sliepen 2006 Scott Lamb This program is free software; you can redistribute it and/or modify @@ -374,11 +374,10 @@ int main_loop(void) { dump_connections(); return 1; } - - continue; } - check_network_activity(&readset, &writeset); + if(r > 0) + check_network_activity(&readset, &writeset); if(do_purge) { purge(); @@ -418,8 +417,13 @@ int main_loop(void) { } if(sigalrm) { + avl_node_t *node; logger(LOG_INFO, "Flushing event queue"); expire_events(); + for(node = connection_tree->head; node; node = node->next) { + connection_t *c = node->data; + send_ping(c); + } sigalrm = false; } diff --git a/src/net_packet.c b/src/net_packet.c index e501153..1f62f64 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -1,7 +1,7 @@ /* net_packet.c -- Handles in- and outgoing VPN packets Copyright (C) 1998-2005 Ivo Timmermans, - 2000-2009 Guus Sliepen + 2000-2010 Guus Sliepen 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 @@ -353,10 +353,10 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { "No valid key known yet for %s (%s), forwarding via TCP", n->name, n->hostname); - if(!n->status.waitingforkey) + if(n->last_req_key + 10 < now) { send_req_key(n); - - n->status.waitingforkey = true; + n->last_req_key = now; + } send_tcppacket(n->nexthop->connection, origpkt); diff --git a/src/net_setup.c b/src/net_setup.c index cbf631f..6360c59 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -1,7 +1,7 @@ /* net_setup.c -- Setup. Copyright (C) 1998-2005 Ivo Timmermans, - 2000-2009 Guus Sliepen + 2000-2010 Guus Sliepen 2006 Scott Lamb This program is free software; you can redistribute it and/or modify @@ -218,8 +218,8 @@ bool setup_myself(void) { myself->connection = new_connection(); init_configuration(&myself->connection->config_tree); - xasprintf(&myself->hostname, "MYSELF"); - xasprintf(&myself->connection->hostname, "MYSELF"); + myself->hostname = xstrdup("MYSELF"); + myself->connection->hostname = xstrdup("MYSELF"); myself->connection->options = 0; myself->connection->protocol_version = PROT_CURRENT; @@ -246,8 +246,9 @@ bool setup_myself(void) { if(!read_rsa_private_key()) return false; - if(!get_config_string(lookup_config(myself->connection->config_tree, "Port"), &myport)) - xasprintf(&myport, "655"); + if(!get_config_string(lookup_config(config_tree, "Port"), &myport) + && !get_config_string(lookup_config(myself->connection->config_tree, "Port"), &myport)) + myport = xstrdup("655"); /* Read in all the subnets specified in the host configuration file */ @@ -296,13 +297,18 @@ bool setup_myself(void) { } else routing_mode = RMODE_ROUTER; - // Enable PMTUDiscovery by default if we are in router mode. - - choice = routing_mode == RMODE_ROUTER; + choice = true; get_config_bool(lookup_config(myself->connection->config_tree, "PMTUDiscovery"), &choice); - if(choice) + get_config_bool(lookup_config(config_tree, "PMTUDiscovery"), &choice); + if(choice) myself->options |= OPTION_PMTU_DISCOVERY; + choice = true; + get_config_bool(lookup_config(config_tree, "ClampMSS"), &choice); + get_config_bool(lookup_config(myself->connection->config_tree, "ClampMSS"), &choice); + if(choice) + myself->options |= OPTION_CLAMP_MSS; + get_config_bool(lookup_config(config_tree, "PriorityInheritance"), &priorityinheritance); #if !defined(SOL_IP) || !defined(IP_TOS) diff --git a/src/net_socket.c b/src/net_socket.c index 46e0532..96e268f 100644 --- a/src/net_socket.c +++ b/src/net_socket.c @@ -1,7 +1,7 @@ /* net_socket.c -- Handle various kinds of sockets. Copyright (C) 1998-2005 Ivo Timmermans, - 2000-2009 Guus Sliepen + 2000-2010 Guus Sliepen 2006 Scott Lamb 2009 Florian Forster @@ -261,9 +261,13 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { option = 1; setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)); -#if defined(SOL_IPV6) && defined(IPV6_V6ONLY) +#if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) if(sa->sa.sa_family == AF_INET6) - setsockopt(nfd, SOL_IPV6, IPV6_V6ONLY, &option, sizeof option); + setsockopt(nfd, IPPROTO_IPV6, IPV6_V6ONLY, &option, sizeof option); +#endif + +#if defined(IP_DONTFRAG) && !defined(IP_DONTFRAGMENT) +#define IP_DONTFRAGMENT IP_DONTFRAG #endif #if defined(SOL_IP) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO) @@ -276,6 +280,8 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { option = 1; setsockopt(nfd, IPPROTO_IP, IP_DONTFRAGMENT, &option, sizeof(option)); } +#else +#warning No way to disable IPv4 fragmentation #endif #if defined(SOL_IPV6) && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO) @@ -283,6 +289,13 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { option = IPV6_PMTUDISC_DO; setsockopt(nfd, SOL_IPV6, IPV6_MTU_DISCOVER, &option, sizeof(option)); } +#elif defined(IPPROTO_IPV6) && defined(IPV6_DONTFRAG) + if(myself->options & OPTION_PMTU_DISCOVERY) { + option = 1; + setsockopt(nfd, IPPROTO_IPV6, IPV6_DONTFRAG, &option, sizeof(option)); + } +#else +#warning No way to disable IPv6 fragmentation #endif if (!bind_to_interface(nfd)) { @@ -331,7 +344,7 @@ void finish_connecting(connection_t *c) { } void do_outgoing_connection(connection_t *c) { - char *address, *port; + char *address, *port, *space; int result; if(!c->outgoing) { @@ -352,8 +365,14 @@ begin: get_config_string(c->outgoing->cfg, &address); - if(!get_config_string(lookup_config(c->config_tree, "Port"), &port)) - xasprintf(&port, "655"); + space = strchr(address, ' '); + if(space) { + port = xstrdup(space + 1); + *space = 0; + } else { + if(!get_config_string(lookup_config(c->config_tree, "Port"), &port)) + port = xstrdup("655"); + } c->outgoing->ai = str2addrinfo(address, port, SOCK_STREAM); free(address); diff --git a/src/node.h b/src/node.h index a621a0a..83e89c7 100644 --- a/src/node.h +++ b/src/node.h @@ -1,6 +1,6 @@ /* node.h -- header for node.c - Copyright (C) 2001-2009 Guus Sliepen , + Copyright (C) 2001-2010 Guus Sliepen , 2001-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -30,7 +30,7 @@ typedef struct node_status_t { int unused_active:1; /* 1 if active (not used for nodes) */ int validkey:1; /* 1 if we currently have a valid key for him */ - int waitingforkey:1; /* 1 if we already sent out a request */ + int unused_waitingforkey:1; /* 1 if we already sent out a request */ int visited:1; /* 1 if this node has been visited by one of the graph algorithms */ int reachable:1; /* 1 if this node is reachable in the graph */ int indirect:1; /* 1 if this node is not directly reachable by us */ @@ -45,6 +45,7 @@ typedef struct node_t { char *hostname; /* the hostname of its real ip */ node_status_t status; + time_t last_req_key; const EVP_CIPHER *incipher; /* Cipher type for UDP packets received from him */ char *inkey; /* Cipher key and iv */ diff --git a/src/protocol.h b/src/protocol.h index e611f6e..703f74b 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -95,7 +95,7 @@ extern bool send_add_subnet(struct connection_t *, const struct subnet_t *); extern bool send_del_subnet(struct connection_t *, const struct subnet_t *); extern bool send_add_edge(struct connection_t *, const struct edge_t *); extern bool send_del_edge(struct connection_t *, const struct edge_t *); -extern bool send_key_changed(); +extern void send_key_changed(); extern bool send_req_key(struct node_t *); extern bool send_ans_key(struct node_t *); extern bool send_tcppacket(struct connection_t *, struct vpn_packet_t *); diff --git a/src/protocol_auth.c b/src/protocol_auth.c index c2df4cd..06735dc 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -1,7 +1,7 @@ /* protocol_auth.c -- handle the meta-protocol, authentication Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2009 Guus Sliepen + 2000-2010 Guus Sliepen 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 @@ -453,6 +453,11 @@ bool send_ack(connection_t *c) { if(myself->options & OPTION_PMTU_DISCOVERY) c->options |= OPTION_PMTU_DISCOVERY; + choice = myself->options & OPTION_CLAMP_MSS; + get_config_bool(lookup_config(c->config_tree, "ClampMSS"), &choice); + if(choice) + c->options |= OPTION_CLAMP_MSS; + get_config_int(lookup_config(c->config_tree, "Weight"), &c->estimated_weight); return send_request(c, "%d %s %d %x", ACK, myport, c->estimated_weight, c->options); @@ -496,6 +501,7 @@ bool ack_h(connection_t *c) { int weight, mtu; uint32_t options; node_t *n; + bool choice; if(sscanf(c->buffer, "%*d " MAX_STRING " %d %x", hisport, &weight, &options) != 3) { logger(LOG_ERR, "Got bad %s from %s (%s)", "ACK", c->name, @@ -536,6 +542,13 @@ bool ack_h(connection_t *c) { if(get_config_int(lookup_config(myself->connection->config_tree, "PMTU"), &mtu) && mtu < n->mtu) n->mtu = mtu; + if(get_config_bool(lookup_config(c->config_tree, "ClampMSS"), &choice)) { + if(choice) + c->options |= OPTION_CLAMP_MSS; + else + c->options &= ~OPTION_CLAMP_MSS; + } + /* Activate this connection */ c->allow_request = ALL; diff --git a/src/protocol_key.c b/src/protocol_key.c index 92948aa..67f40af 100644 --- a/src/protocol_key.c +++ b/src/protocol_key.c @@ -1,7 +1,7 @@ /* protocol_key.c -- handle the meta-protocol, key exchange Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2009 Guus Sliepen + 2000-2010 Guus Sliepen 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 @@ -36,15 +36,19 @@ bool mykeyused = false; -bool send_key_changed() { - /* Only send this message if some other daemon requested our key previously. - This reduces unnecessary key_changed broadcasts. - */ +void send_key_changed() { + avl_node_t *node; + connection_t *c; - if(!mykeyused) - return true; + send_request(broadcast, "%d %x %s", KEY_CHANGED, rand(), myself->name); - return send_request(broadcast, "%d %x %s", KEY_CHANGED, rand(), myself->name); + /* Immediately send new keys to directly connected nodes to keep UDP mappings alive */ + + for(node = connection_tree->head; node; node = node->next) { + c = node->data; + if(c->status.active && c->node && c->node->status.reachable) + send_ans_key(c->node); + } } bool key_changed_h(connection_t *c) { @@ -57,6 +61,11 @@ bool key_changed_h(connection_t *c) { return false; } + if(!check_id(name)) { + logger(LOG_ERR, "Got bad %s from %s (%s): %s", "KEY_CHANGED", c->name, c->hostname, "invalid name"); + return false; + } + if(seen_request(c->buffer)) return true; @@ -65,11 +74,11 @@ bool key_changed_h(connection_t *c) { if(!n) { logger(LOG_ERR, "Got %s from %s (%s) origin %s which does not exist", "KEY_CHANGED", c->name, c->hostname, name); - return false; + return true; } n->status.validkey = false; - n->status.waitingforkey = false; + n->last_req_key = 0; /* Tell the others */ @@ -94,12 +103,17 @@ bool req_key_h(connection_t *c) { return false; } + if(!check_id(from_name) || !check_id(to_name)) { + logger(LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_KEY", c->name, c->hostname, "invalid name"); + return false; + } + from = lookup_node(from_name); if(!from) { logger(LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list", "REQ_KEY", c->name, c->hostname, from_name); - return false; + return true; } to = lookup_node(to_name); @@ -107,7 +121,7 @@ bool req_key_h(connection_t *c) { if(!to) { logger(LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list", "REQ_KEY", c->name, c->hostname, to_name); - return false; + return true; } /* Check if this key request is for us */ @@ -116,7 +130,7 @@ bool req_key_h(connection_t *c) { send_ans_key(from); } else { if(tunnelserver) - return false; + return true; if(!to->status.reachable) { logger(LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable", @@ -169,23 +183,30 @@ bool ans_key_h(connection_t *c) { char from_name[MAX_STRING_SIZE]; char to_name[MAX_STRING_SIZE]; char key[MAX_STRING_SIZE]; + char address[MAX_STRING_SIZE] = ""; + char port[MAX_STRING_SIZE] = ""; int cipher, digest, maclength, compression; node_t *from, *to; - if(sscanf(c->buffer, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %d %d", + if(sscanf(c->buffer, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %d %d "MAX_STRING" "MAX_STRING, from_name, to_name, key, &cipher, &digest, &maclength, - &compression) != 7) { + &compression, address, port) < 7) { logger(LOG_ERR, "Got bad %s from %s (%s)", "ANS_KEY", c->name, c->hostname); return false; } + if(!check_id(from_name) || !check_id(to_name)) { + logger(LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_KEY", c->name, c->hostname, "invalid name"); + return false; + } + from = lookup_node(from_name); if(!from) { logger(LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list", "ANS_KEY", c->name, c->hostname, from_name); - return false; + return true; } to = lookup_node(to_name); @@ -193,14 +214,14 @@ bool ans_key_h(connection_t *c) { if(!to) { logger(LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list", "ANS_KEY", c->name, c->hostname, to_name); - return false; + return true; } /* Forward it if necessary */ if(to != myself) { if(tunnelserver) - return false; + return true; if(!to->status.reachable) { logger(LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable", @@ -208,6 +229,16 @@ bool ans_key_h(connection_t *c) { return true; } + if(!*address) { + char *address, *port; + ifdebug(PROTOCOL) logger(LOG_DEBUG, "Appending reflexive UDP address to ANS_KEY from %s to %s", from->name, to->name); + sockaddr2str(&from->address, &address, &port); + send_request(to->nexthop->connection, "%s %s %s", c->buffer, address, port); + free(address); + free(port); + return true; + } + return send_request(to->nexthop->connection, "%s", c->buffer); } @@ -218,7 +249,6 @@ bool ans_key_h(connection_t *c) { from->outkeylength = strlen(key) / 2; hex2bin(key, from->outkey, from->outkeylength); - from->status.waitingforkey = false; /* Check and lookup cipher and digest algorithms */ if(cipher) { @@ -227,13 +257,13 @@ bool ans_key_h(connection_t *c) { if(!from->outcipher) { logger(LOG_ERR, "Node %s (%s) uses unknown cipher!", from->name, from->hostname); - return false; + return true; } if(from->outkeylength != from->outcipher->key_len + from->outcipher->iv_len) { logger(LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname); - return false; + return true; } } else { from->outcipher = NULL; @@ -247,13 +277,13 @@ bool ans_key_h(connection_t *c) { if(!from->outdigest) { logger(LOG_ERR, "Node %s (%s) uses unknown digest!", from->name, from->hostname); - return false; + return true; } if(from->outmaclength > from->outdigest->md_size || from->outmaclength < 0) { logger(LOG_ERR, "Node %s (%s) uses bogus MAC length!", from->name, from->hostname); - return false; + return true; } } else { from->outdigest = NULL; @@ -261,7 +291,7 @@ bool ans_key_h(connection_t *c) { if(compression < 0 || compression > 11) { logger(LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname); - return false; + return true; } from->outcompression = compression; @@ -270,12 +300,18 @@ bool ans_key_h(connection_t *c) { if(!EVP_EncryptInit_ex(&from->outctx, from->outcipher, NULL, (unsigned char *)from->outkey, (unsigned char *)from->outkey + from->outcipher->key_len)) { logger(LOG_ERR, "Error during initialisation of key from %s (%s): %s", from->name, from->hostname, ERR_error_string(ERR_get_error(), NULL)); - return false; + return true; } from->status.validkey = true; from->sent_seqno = 0; + if(*address && *port) { + ifdebug(PROTOCOL) logger(LOG_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port); + sockaddr_t sa = str2sockaddr(address, port); + update_node_udp(from, &sa); + } + if(from->options & OPTION_PMTU_DISCOVERY && !from->mtuprobes) send_mtu_probe(from); diff --git a/src/route.c b/src/route.c index 5c69671..664fed8 100644 --- a/src/route.c +++ b/src/route.c @@ -1,7 +1,7 @@ /* route.c -- routing Copyright (C) 2000-2005 Ivo Timmermans, - 2000-2009 Guus Sliepen + 2000-2010 Guus Sliepen 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 @@ -48,6 +48,7 @@ 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)) /* RFC 1071 */ @@ -92,6 +93,74 @@ static bool checklength(node_t *source, vpn_packet_t *packet, length_t length) { return true; } +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)) + return; + + /* Find TCP header */ + int start = 0; + uint16_t type = packet->data[12] << 8 | packet->data[13]; + + if(type == ETH_P_IP && packet->data[23] == 6) + start = 14 + (packet->data[14] & 0xf) * 4; + else if(type == ETH_P_IPV6 && packet->data[20] == 6) + start = 14 + 40; + + if(!start || packet->len <= start + 20) + return; + + /* Use data offset field to calculate length of options field */ + int len = ((packet->data[start + 12] >> 4) - 5) * 4; + + if(packet->len < start + 20 + len) + return; + + /* Search for MSS option header */ + for(int i = 0; i < len;) { + if(packet->data[start + 20 + i] == 0) + break; + + if(packet->data[start + 20 + i] == 1) { + i++; + continue; + } + + if(i > len - 2 || i > len - packet->data[start + 21 + i]) + break; + + if(packet->data[start + 20 + i] != 2) { + if(packet->data[start + 21 + i] < 2) + break; + i += packet->data[start + 21 + i]; + continue; + } + + if(packet->data[start + 21] != 4) + break; + + /* 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 csum = packet->data[start + 16] << 8 | packet->data[start + 17]; + + if(oldmss <= newmss) + break; + + ifdebug(TRAFFIC) logger(LOG_INFO, "Clamping MSS of packet from %s to %s to %d", source->name, via->name, newmss); + + /* Update the MSS value and the checksum */ + packet->data[start + 22 + i] = newmss >> 8; + packet->data[start + 23 + i] = newmss & 0xff; + csum ^= 0xffff; + csum -= oldmss; + csum += newmss; + csum ^= 0xffff; + packet->data[start + 16] = csum >> 8; + packet->data[start + 17] = csum & 0xff; + break; + } +} + static void swap_mac_addresses(vpn_packet_t *packet) { mac_t tmp; memcpy(&tmp, &packet->data[0], sizeof tmp); @@ -104,7 +173,7 @@ static void learn_mac(mac_t *address) { avl_node_t *node; connection_t *c; - subnet = lookup_subnet_mac(address); + subnet = lookup_subnet_mac(myself, address); /* If we don't know this MAC address yet, store it */ @@ -119,6 +188,7 @@ static void learn_mac(mac_t *address) { subnet->net.mac.address = *address; subnet->weight = 10; subnet_add(myself, subnet); + subnet_update(myself, subnet, true); /* And tell all other tinc daemons it's our MAC */ @@ -154,6 +224,7 @@ void age_subnets(void) { send_del_subnet(c, s); } + subnet_update(myself, s, false); subnet_del(myself, s); } } @@ -315,10 +386,10 @@ static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) { via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via; - if(via && packet->len > via->mtu && via != myself) { + 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 = via->mtu; + packet->len = max(via->mtu, 590); route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED); } else { fragment_ipv4_packet(via, packet); @@ -327,6 +398,8 @@ static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) { return; } + clamp_mss(source, via, packet); + send_packet(subnet->owner, packet); } @@ -458,13 +531,15 @@ static void route_ipv6_unicast(node_t *source, vpn_packet_t *packet) { via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via; - if(via && packet->len > via->mtu && via != myself) { + 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 = via->mtu; + packet->len = max(via->mtu, 1294); route_ipv6_unreachable(source, packet, ICMP6_PACKET_TOO_BIG, 0); return; } + clamp_mss(source, via, packet); + send_packet(subnet->owner, packet); } @@ -705,7 +780,7 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { /* Lookup destination address */ memcpy(&dest, &packet->data[0], sizeof dest); - subnet = lookup_subnet_mac(&dest); + subnet = lookup_subnet_mac(NULL, &dest); if(!subnet) { broadcast_packet(source, packet); @@ -724,7 +799,7 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { 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); uint16_t type = packet->data[12] << 8 | packet->data[13]; - if(type == ETH_P_IP) { + if(type == ETH_P_IP && packet->len > 590) { if(packet->data[20] & 0x40) { packet->len = via->mtu; route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED); @@ -732,13 +807,15 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { fragment_ipv4_packet(via, packet); } return; - } else if(type == ETH_P_IPV6) { + } else if(type == ETH_P_IPV6 && packet->len > 1294) { packet->len = via->mtu; route_ipv6_unreachable(source, packet, ICMP6_PACKET_TOO_BIG, 0); return; } } + clamp_mss(source, via, packet); + send_packet(subnet->owner, packet); } diff --git a/src/subnet.c b/src/subnet.c index 3d1168d..67be001 100644 --- a/src/subnet.c +++ b/src/subnet.c @@ -1,6 +1,6 @@ /* subnet.c -- handle subnet lookups and lists - Copyright (C) 2000-2009 Guus Sliepen , + Copyright (C) 2000-2010 Guus Sliepen , 2000-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -329,8 +329,8 @@ subnet_t *lookup_subnet(const node_t *owner, const subnet_t *subnet) { return avl_search(owner->subnet_tree, subnet); } -subnet_t *lookup_subnet_mac(const mac_t *address) { - subnet_t *p, *r = NULL, subnet = {0}; +subnet_t *lookup_subnet_mac(const node_t *owner, const mac_t *address) { + subnet_t *p, *r = NULL; avl_node_t *n; int i; @@ -339,20 +339,18 @@ subnet_t *lookup_subnet_mac(const mac_t *address) { for(i = 0; i < 2; i++) { if(!cache_mac_valid[i]) continue; + if(owner && cache_mac_subnet[i] && cache_mac_subnet[i]->owner != owner) + continue; if(!memcmp(address, &cache_mac_address[i], sizeof *address)) return cache_mac_subnet[i]; } // Search all subnets for a matching one - subnet.type = SUBNET_MAC; - subnet.net.mac.address = *address; - subnet.owner = NULL; - - for(n = subnet_tree->head; n; n = n->next) { + for(n = owner ? owner->subnet_tree->head : subnet_tree->head; n; n = n->next) { p = n->data; - if(!p || p->type != subnet.type) + if(!p || p->type != SUBNET_MAC) continue; if(!memcmp(address, &p->net.mac.address, sizeof *address)) { @@ -373,7 +371,7 @@ subnet_t *lookup_subnet_mac(const mac_t *address) { } subnet_t *lookup_subnet_ipv4(const ipv4_t *address) { - subnet_t *p, *r = NULL, subnet = {0}; + subnet_t *p, *r = NULL; avl_node_t *n; int i; @@ -388,15 +386,10 @@ subnet_t *lookup_subnet_ipv4(const ipv4_t *address) { // Search all subnets for a matching one - subnet.type = SUBNET_IPV4; - subnet.net.ipv4.address = *address; - subnet.net.ipv4.prefixlength = 32; - subnet.owner = NULL; - for(n = subnet_tree->head; n; n = n->next) { p = n->data; - if(!p || p->type != subnet.type) + if(!p || p->type != SUBNET_IPV4) continue; if(!maskcmp(address, &p->net.ipv4.address, p->net.ipv4.prefixlength)) { @@ -417,7 +410,7 @@ subnet_t *lookup_subnet_ipv4(const ipv4_t *address) { } subnet_t *lookup_subnet_ipv6(const ipv6_t *address) { - subnet_t *p, *r = NULL, subnet = {0}; + subnet_t *p, *r = NULL; avl_node_t *n; int i; @@ -432,15 +425,10 @@ subnet_t *lookup_subnet_ipv6(const ipv6_t *address) { // Search all subnets for a matching one - subnet.type = SUBNET_IPV6; - subnet.net.ipv6.address = *address; - subnet.net.ipv6.prefixlength = 128; - subnet.owner = NULL; - for(n = subnet_tree->head; n; n = n->next) { p = n->data; - if(!p || p->type != subnet.type) + if(!p || p->type != SUBNET_IPV6) continue; if(!maskcmp(address, &p->net.ipv6.address, p->net.ipv6.prefixlength)) { @@ -490,7 +478,7 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) { if(!net2str(netstr, sizeof netstr, subnet)) continue; // Strip the weight from the subnet, and put it in its own environment variable - char *weight = strchr(netstr + 7, '#'); + char *weight = strchr(netstr, '#'); if(weight) *weight++ = 0; else @@ -507,9 +495,9 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) { execute_script(name, envp); } } else { - if(net2str(netstr + 7, sizeof netstr - 7, subnet)) { + if(net2str(netstr, sizeof netstr, subnet)) { // Strip the weight from the subnet, and put it in its own environment variable - char *weight = strchr(netstr + 7, '#'); + char *weight = strchr(netstr, '#'); if(weight) *weight++ = 0; else diff --git a/src/subnet.h b/src/subnet.h index c9bb10e..b2124a0 100644 --- a/src/subnet.h +++ b/src/subnet.h @@ -77,7 +77,7 @@ extern void subnet_update(struct node_t *, subnet_t *, bool); extern bool net2str(char *, int, const subnet_t *); extern bool str2net(subnet_t *, const char *); extern subnet_t *lookup_subnet(const struct node_t *, const subnet_t *); -extern subnet_t *lookup_subnet_mac(const mac_t *); +extern subnet_t *lookup_subnet_mac(const struct node_t *, const mac_t *); extern subnet_t *lookup_subnet_ipv4(const ipv4_t *); extern subnet_t *lookup_subnet_ipv6(const ipv6_t *); extern void dump_subnets(void); diff --git a/src/tincd.c b/src/tincd.c index 8c2b12d..7779430 100644 --- a/src/tincd.c +++ b/src/tincd.c @@ -1,7 +1,7 @@ /* tincd.c -- the main file for tincd Copyright (C) 1998-2005 Ivo Timmermans - 2000-2009 Guus Sliepen + 2000-2010 Guus Sliepen 2008 Max Rijevski 2009 Michael Tokarev @@ -500,7 +500,7 @@ int main(int argc, char **argv) { if(show_version) { printf("%s version %s (built %s %s, protocol %d)\n", PACKAGE, VERSION, __DATE__, __TIME__, PROT_CURRENT); - printf("Copyright (C) 1998-2009 Ivo Timmermans, Guus Sliepen and others.\n" + printf("Copyright (C) 1998-2010 Ivo Timmermans, Guus Sliepen and others.\n" "See the AUTHORS file for a complete list.\n\n" "tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n" "and you are welcome to redistribute it under certain conditions;\n"